- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写的套接字程序是客户端向服务器发送一个字符串数组,服务器接收该数组并发回给客户端。我的服务器可以在服务器端成功打印出字符串数组reply[]。但在客户端,却无法打印出结果。这是我的代码
客户端.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 4444
int main(int argc, char *argv[]){
if (argc < 2 || argc > 3) // Test for correct number of arguments
printf("Parameter(): <Server Address>");
char *servIP = argv[1]; // arg: server IP address (dotted quad)
int clientSocket, ret;
struct sockaddr_in serverAddr; // Server address
char buffer[1024];
char **reply = malloc(20*sizeof(char *));
// Create a reliable, stream socket using TCP
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
// Construct the server address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Server port
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &serverAddr.sin_addr.s_addr);
if (rtnVal == 0)
printf("inet_pton() failed: invalid address string");
else if (rtnVal < 0)
printf("inet_pton() failed");
// Establish the connection to the sorted server
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to Server.\n");
//Read arrays from input file
FILE *fptr;
fptr = fopen("client1.inputdat", "r"); //open input file to read
if (fptr != NULL)
{
int line =0;
while(fgets(buffer, sizeof(buffer), fptr)) { //read line by line of the input file
line++;
if (line==1) {
printf("\n");
printf("Unsorted array: %s\n", buffer);
// Send arrays to the server
send(clientSocket, buffer, strlen(buffer), 0);
// Receive the sorted arrays back from the server
if(recv(clientSocket, &reply, 20*sizeof(char *), 0) < 0){
printf("Error in receiving data.\n");
}
else {
int i;
printf("Sorted array:");
for (i=0; i<20; i++) {
reply[i] = malloc(10*sizeof(char));
printf("%s ", reply[i]);
}
}
}
}
fclose(fptr);
}
else {
printf("File does not exits");
exit(1);
}
return 0;
}
服务器.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
int main(){
int sockfd, ret;
struct sockaddr_in serverAddr; // Local address
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
char buffer[1024];
pid_t childpid;
// Create socket for incoming connections
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
// Construct local address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Local port
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
// Bind to the local address
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding.\n");
exit(1);
}
printf("Bind to port %d\n", 4444);
// Mark the socket so it will listen for incoming connections
if(listen(sockfd, 10) == 0){ //Maximum outstanding connection requests is 10
printf("Listening....\n");
}else{
printf("Error in binding.\n");
}
while(1){
// Wait for clients to connect
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
// newSocket is connected to client!
char newName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &newAddr.sin_addr.s_addr, newName, sizeof(newName)) != NULL)
printf("Handling client %s/ %d\n", newName, ntohs(newAddr.sin_port));
else
printf("Unable to get client address");
//Handle concurrency by using fork
if((childpid = fork()) == 0){
close(sockfd);
while(1){
recv(newSocket, buffer, 1024, 0);
int i=0;
char *array[20];
char **reply = malloc(20*sizeof(char *));
char *p = strtok(buffer, ",");
while (p!=NULL) {
array[i++] = p;
p = strtok(NULL, ","); //stroke received string into tokens
}
for (i=0; i<20; i++) {
reply[i] = malloc(10*sizeof(char));
strcpy(reply[i], array[i]); //input tokens into array
printf("%s ", reply[i]);
}
send(newSocket, reply, 20*sizeof(char *), 0);
bzero(reply, sizeof(reply));
//}
}
}
}
close(newSocket);
return 0;
}
那么,我该如何解决这个问题,以便客户端可以打印出服务器发送的数组reply[]?谢谢你的补充
最佳答案
好的。你的代码很清楚地表明你不太了解C,更不用说套接字了,但这里有一个新的改进版本,我认为它可以满足你的要求。我的大部分改进都包含在对原始帖子的评论中。我没有在适当的地方检查错误,这在许多其他方面都远非完美,但这会做一些看起来像你想要的事情,而不会崩溃。
您在发送数据时没有任何方式知道您是否收到了所有传输的数据。套接字是流。它以它认为最方便的方式发送数据,而不是您可能喜欢的方式。为了解决这个问题,我要求我们发送 \n
每次传输。我们检查 \n
并在每次从对方返回数据时继续读取数据。我发送了很多条回复数据后,我发送了一条\n
字符,以便客户知道已收到完整的行。我们不需要添加\n
来自客户 fgets
离开\n
在缓冲区的末尾。
你提到了排序,所以作为额外的奖励,我添加了 qsort
对数据进行排序。在 compReply
函数,我不只是直接从 strcmp
返回值但将其放入 int
所以如果需要的话我可以在调试器中看到它。我相信有些编译器会提示我正在做 strcmp
两个void *
变量。为了保持整洁,您可能需要使用 (char*)a
来转换它们。在将它们传递给 strcmp
之前.
我删除了你的fork
以便于调试。抱歉,这一次只允许一个连接。当我写这样的东西时,我通常不会 fork 一个新进程,而是拥有一个 newSocket 值数组并使用 select
来决定从哪一个中读取。 (select
函数也可以与 accept
一起使用。)同样,这样调试起来更容易。
strtok
函数将找到的字符替换为 null,并返回指向字符串开头的指针。我只是想删除不需要的字符,所以我使用它而不费心接受返回值。这也可以通过以下方式完成:
char *p=strchr(buffer,'\n');
if( NULL != p ) *p=0;
但是strtok
更加简洁。
我允许将端口号传递到服务器,但没有将其添加到客户端。哦,好吧。
在让客户端运行之前我测试了服务器
telnet 127.0.0.1 4444
并输入:a,s,d,f,g,h,j,k,l <CR>
返回排序后的列表 a,d,f,g,h,j,k,l,s,
我也不喜欢结尾的逗号,但我现在不会让它消失。
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
#define BUF_SIZE 1024
static int compReply(const void *a, const void *b)
{
int ret=strcmp(a,b);
return(ret);
}
int main(int argc, char *argv[])
{
int port=4444;
int sockfd, ret;
struct sockaddr_in serverAddr; // Local address
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
if( argc > 1 ) {
port=atoi(argv[1]);
if( port < 1024 ) {
port=4444;
}
}
// Create socket for incoming connections
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
// Construct local address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Local port
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
// Bind to the local address
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding.\n");
perror("bind");
exit(1);
}
printf("Bind to port %d\n", port);
// Mark the socket so it will listen for incoming connections
if(listen(sockfd, 10) == 0){ //Maximum outstanding connection requests is 10
printf("Listening....\n");
}else{
printf("Error in listening.\n");
perror("listen");
}
while(1){
// Wait for clients to connect
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
// newSocket is connected to client!
char newName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &newAddr.sin_addr.s_addr, newName, sizeof(newName)) != NULL)
printf("Handling client %s/ %d\n", newName, ntohs(newAddr.sin_port));
else
printf("Unable to get client address");
while(1){
char buffer[BUF_SIZE]={0};
int ret=1;
int count=0;
while(NULL == strchr(buffer,'\n') && ret > 0 && count < sizeof(buffer))
{
ret=recv(newSocket, &buffer[count], sizeof(buffer)-count, 0);
count+=ret;
}
if( ret <= 0 ) {
if( ret < 0 ) {
printf("Problem with recv: %d\n", ret);
}
break;
}
printf("recv: %s\n", buffer);
strtok(buffer,"\n\r"); /* throw away any \r\n */
if( ret> 0 ) {
int i=0;
char reply[20][BUF_SIZE]={0};
char *p = strtok(buffer, ",");
while (p!=NULL) {
strncpy(reply[i],p,BUF_SIZE);
strcat(reply[i],",");
p = strtok(NULL, ","); //stroke received string into tokens
i++;
}
qsort(reply,i,BUF_SIZE,compReply);
for(int jj=0; jj<i; jj++) {
printf("%s ", reply[jj]);
ret=send(newSocket, reply[jj], strlen(reply[jj]), 0);
}
ret=send(newSocket, "\n", 1, 0);
printf("\n");
}
}
close(newSocket);
}
return 0;
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 4444
#define BUF_SIZE 1024
int main(int argc, char *argv[])
{
char servIP[120]="127.0.0.1";
if( argc > 1 ) {
strncpy(servIP,argv[1],sizeof(servIP));
}
int clientSocket, ret;
struct sockaddr_in serverAddr; // Server address
char buffer[BUF_SIZE];
// Create a reliable, stream socket using TCP
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
// Construct the server address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Server port
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &serverAddr.sin_addr.s_addr);
if (rtnVal == 0)
printf("inet_pton() failed: invalid address string");
else if (rtnVal < 0)
printf("inet_pton() failed");
// Establish the connection to the sorted server
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to Server.\n");
//Read arrays from input file
FILE *fptr;
fptr = fopen("this.csv", "r"); //open input file to read
if (fptr != NULL) {
while(fgets(buffer, sizeof(buffer), fptr)) //read line by line of the input file
{
char reply[BUF_SIZE]={0};
char repList[20][BUF_SIZE]={0};
int count=0;
int ret=1;
printf("Unsorted array: %s", buffer);
// Send array to the server
send(clientSocket, buffer, strlen(buffer), 0);
// Receive the sorted arrays back from the server
while(NULL == strchr(reply,'\n') && ret > 0 && count < sizeof(reply))
{
ret=recv(clientSocket, &reply[count],sizeof(reply)-count,0);
count+=ret;
}
if( ret < 0 ) {
printf("Error in receiving data.\n");
}
else {
int i=0;
strtok(reply,"\n\r");
for(char *p=strtok(reply,",");p!=NULL; p=strtok(NULL,","))
{
strncpy(repList[i],p,BUF_SIZE);
i++;
}
printf("Sorted array:");
for (int jj=0; jj<i; jj++) {
printf("%s ", repList[jj]);
}
}
printf("\n");
}
fclose(fptr);
}
else {
printf("File does not exist");
perror("fopen");
exit(1);
}
return 0;
}
这应该会给你一些可以尝试的东西来帮助你继续前进。我希望它有帮助。
关于c - C 中的套接字 : Client can not receive and print out the array of strings sent from server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53127386/
我遇到了一个错误,我不知道如何解决。我有以下代码(来自 Eliom Graffiti 教程),我正在尝试使用 make test.byte 进行测试。 open Eliom_content.Html5
我阅读文档的理解是这样的: 客户端是测试用例的子类。当我们运行 manage.py test 时,会为每个以“test_”开头的方法创建一个 SimpleTest 类的实例(它继承自 TestCase
我已经编写了一个用于接收多个客户端的服务器,它可以分别与客户端通信。在这里,我可以列出服务器中已连接的客户端,但是当客户端断开连接时,它不会从服务器中删除客户端。 Server.py import s
我正在制作一个社交网站。当任何用户在站点上更新或创建新内容时,我需要查看站点的任何其他用户来查看更改更新。 我有一些需要低延迟的评论,因此建议为此订阅。 我也有事件,但这些不需要这么低的延迟。每 10
我想在突变后使用乐观 UI 更新:https://www.apollographql.com/docs/react/basics/mutations.html 我对“乐观响应”和“更新”之间的关系感到
我想了解 Dask 在本地机器上的使用模式。 具体而言, 我有一个适合内存的数据集 我想做一些 pandas 操作 分组依据... 日期解析 等等 Pandas 通过单核执行这些操作,这些操作对我来说
我使用 Apollo、React 和 Graphcool。我有一个查询来获取登录的用户 ID: const LoginServerQuery = gql` query LoginServerQ
在本指南的帮助下,我最近在几个设备的应用程序中设置了 P2P 通信:http://developer.android.com/training/connect-devices-wirelessly/n
注意:我在节点项目中使用@twilio/conversations 1.1.0 版。我正在从使用可编程聊天过渡到对话。 我看到对 Client.getConversationByUniqueName
我对服务客户端和设备客户端库有点困惑。谁能解答我对此的疑问。 问题:当我通过 deviceClient 发送数据时,我无法接收数据,但当我使用服务客户端发送数据时,相同的代码可以工作。现在,xamar
我对服务客户端和设备客户端库有点困惑。谁能解答我对此的疑问。 问题:当我通过 deviceClient 发送数据时,我无法接收数据,但当我使用服务客户端发送数据时,相同的代码可以工作。现在,xamar
假设我有一个简单的应用程序。 如何设置 OAuth2 以允许其他应用程序访问我的应用程序的某些部分。 例如,当开发人员想要使用 Facebook API 时,他们会使用 Facebook API 用户
我有两个模块: 在一个模块中,我从另一个模块run 中引用了一个函数: @myorg/server import { Client } from '.' import { Middleware } f
我在通过服务器从客户端向客户端发送数据时遇到了一些问题(以避免监听客户端上的端口)。 我有一个这样的服务器: var net = require("net"); var server = net.cr
我正在使用 django.test.client.Client 来测试用户登录时是否显示某些文本。但是,我的 Client 对象似乎并没有让我保持登录状态。 如果使用 Firefox 手动完成,则此测
有两个我制作的程序无法运行。有服务器和客户端。服务器通过给用户一个 ID(从 0 开始)来接受许多客户端。服务器根据服务器的 ID 将命令发送到特定的客户端。 (示例:200 个客户端连接到 1 个服
今天,我在 Windows 10 的“程序和功能”列表中看到了 2 个不同版本的 ARC,因此我选择卸载旧版本,因为我需要一些空间。在卸载结束时,它们都消失了! 所以,我从 https://insta
在每个新的客户端连接上 fork 服务器进程 不同的进程(服务器的其他子进程,即 exec)无法识别在 fork 子进程中使用相同 fd 的客户端。 如何在其他进程上区分客户端? 如果文件描述符为新
a和b有什么区别? >>> import boto3 >>> a = boto3.Session().client("s3") >>> b = boto3.client("s3") >>> a ==
a和b有什么区别? >>> import boto3 >>> a = boto3.Session().client("s3") >>> b = boto3.client("s3") >>> a ==
我是一名优秀的程序员,十分优秀!