Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C套接字编程,服务器发送缓冲区似乎没有被清除_C_Sockets - Fatal编程技术网

C套接字编程,服务器发送缓冲区似乎没有被清除

C套接字编程,服务器发送缓冲区似乎没有被清除,c,sockets,C,Sockets,我对socket编程非常陌生,我对它有困难。我想实现一个服务器,它根据特定的客户端请求进行应答。在我的例子中,要么是GET,HEAD,要么是一个错误。考虑下面的代码 如果在调用send()(请参阅下面的服务器端代码)之前打印答案,则消息是正确的。但我想说的是我的客户 得到 头 得到 试验 得到 ,从客户端打印的答案是 You want GET You want HEAD You want GETD HTTP/1.1 400 Bad Request You want GET Bad Request

我对socket编程非常陌生,我对它有困难。我想实现一个服务器,它根据特定的客户端请求进行应答。在我的例子中,要么是GET,HEAD,要么是一个错误。考虑下面的代码

如果在调用
send()
(请参阅下面的服务器端代码)之前打印答案,则消息是正确的。但我想说的是我的客户

  • 得到
  • 得到
  • 试验
  • 得到
  • ,从客户端打印的答案是

    You want GET
    You want HEAD
    You want GETD
    HTTP/1.1 400 Bad Request
    You want GET Bad Request
    
    因此,从服务器发送的消息似乎有点“被覆盖”,但这是如何避免的呢?如果这是问题所在,是否可以“清除服务器缓冲区”

    这是完整的服务器端代码

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    
    #define BUFSIZE         1024
    #define MAXPENDING      100
    
    int main(){
    
        char get[] = "GET";
        char head[] = "HEAD";
        int serverSocket = socket(PF_INET, SOCK_STREAM, 0);
    
        struct sockaddr_in serverAddress;
        serverAddress.sin_family = AF_INET;
        serverAddress.sin_port = htons(8080);
        serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
        memset(&serverAddress.sin_zero, '\0', 8);
    
        bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
    
        listen(serverSocket, MAXPENDING);
    
        for(;;){
            struct sockaddr_in clientAddress;
            int clientAddressLength = sizeof(clientAddress);
            int clientSocket;
    
            clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);
    
            char buf[BUFSIZE];
            int bytesRec;
    
            bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
            while(bytesRec > 0){
    
                char *result;
                result = strtok(buf, " ");
    
                printf("result %s\n", result);
    
                if(strcmp(&buf, &get) == 0){
                    char answer[] = "You want GET";
                    send(clientSocket, answer, strlen(answer), 0);
                }else{
                    if(strcmp(&buf, &head) == 0){
                        char answer[] = "You want HEAD";
                        send(clientSocket, answer, strlen(answer), 0);
                    }else{
                        char answer[] = "HTTP/1.1 400 Bad Request";
                        send(clientSocket, answer, strlen(answer), 0); 
                    }
                }
    
                bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
            }
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #定义bufsize1024
    #定义MAXPENDING 100
    int main(){
    char get[]=“get”;
    字符头[]=“头”;
    int serverSocket=socket(PF_INET,SOCK_STREAM,0);
    serverAddress中的结构sockaddr_;
    serverAddress.sin_family=AF_INET;
    serverAddress.sin_port=htons(8080);
    serverAddress.sin\u addr.s\u addr=htonl(INADDR\u ANY);
    memset(&serverAddress.sin_zero,'\0',8);
    绑定(serverSocket,(struct sockaddr*)&serverAddress,sizeof(serverAddress));
    侦听(serverSocket,MAXPENDING);
    对于(;;){
    clientAddress中的结构sockaddr_;
    int clientAddress length=sizeof(clientAddress);
    int客户端套接字;
    clientSocket=accept(serverSocket,(struct sockaddr*)&clientAddress,&clientAddress长度);
    字符buf[BUFSIZE];
    int bytesRec;
    bytesRec=recv(clientSocket,buf,BUFSIZE,0);
    while(bytesRec>0){
    字符*结果;
    结果=strtok(buf,“”);
    printf(“结果%s\n”,结果);
    if(strcmp(&buf,&get)==0){
    char-answer[]=“您想要得到”;
    发送(客户端套接字,应答,strlen(应答),0);
    }否则{
    如果(strcmp(&buf,&head)==0){
    char-answer[]=“您想要头部”;
    发送(客户端套接字,应答,strlen(应答),0);
    }否则{
    char-answer[]=“HTTP/1.1 400错误请求”;
    发送(客户端套接字,应答,strlen(应答),0);
    }
    }
    bytesRec=recv(clientSocket,buf,BUFSIZE,0);
    }
    返回0;
    }
    
    还有客户端

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    
    int main(){
    
        int clientSocket = socket(PF_INET, SOCK_STREAM, 0);
    
        struct sockaddr_in clientAddress;
        clientAddress.sin_family = AF_INET;
        clientAddress.sin_port = 0;
        clientAddress.sin_addr.s_addr = htonl(INADDR_ANY);
        memset(&clientAddress.sin_zero, '\0', 8/*sizeof(clientAddress.sin_zero)*/);
    
        bind(clientSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
    
        struct sockaddr_in serverAddress;
        serverAddress.sin_family = AF_INET;
        serverAddress.sin_port = htons(8080);
        serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
        memset(&serverAddress.sin_zero, '\0', 8);
    
        if(connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1){
            printf("error in connecting!\n");
            return 0;
        }
    
        char* serverReply[1024];
    
        for(;;){
            char request[100];
            printf("Enter your request: ");
            scanf("%s", &request);
            send(clientSocket, request, strlen(msg), 0);
            if(recv(clientSocket, serverReply, strlen(serverReply), 0) < 0){
                printf("failure in receiving from server!\n");
            }else{
                printf("%s\n", serverReply);
            }
        }
    
        close(clientSocket);
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    int main(){
    int clientSocket=socket(PF_INET,SOCK_STREAM,0);
    clientAddress中的结构sockaddr_;
    clientAddress.sin_family=AF_INET;
    clientAddress.sin_端口=0;
    clientAddress.sin\u addr.s\u addr=htonl(INADDR\u ANY);
    memset(&clientAddress.sin_zero,“\0',8/*sizeof(clientAddress.sin_zero)*/);
    绑定(clientSocket,(struct sockaddr*)&clientAddress,sizeof(clientAddress));
    serverAddress中的结构sockaddr_;
    serverAddress.sin_family=AF_INET;
    serverAddress.sin_port=htons(8080);
    serverAddress.sin_addr.s_addr=inet_addr(“127.0.0.1”);
    memset(&serverAddress.sin_zero,'\0',8);
    if(connect(clientSocket,(struct sockaddr*)&serverAddress,sizeof(serverAddress))=-1){
    printf(“连接错误!\n”);
    返回0;
    }
    char*serverReply[1024];
    对于(;;){
    字符请求[100];
    printf(“输入您的请求:”);
    scanf(“%s”,请求(&R));
    发送(clientSocket,请求,strlen(msg),0);
    if(recv(clientSocket,serverReply,strlen(serverReply),0)<0){
    printf(“从服务器接收失败!\n”);
    }否则{
    printf(“%s\n”,serverReply);
    }
    }
    关闭(clientSocket);
    返回0;
    }
    
    如果您的
    strcmp()
    错误

    (1)您需要与
    结果进行比较,而不是像我从您的问题中所理解的那样进行比较,比如:(您在评论中说结果打印为GET)

    (2)正如@phihag回答的那样

    if(strcmp(buf, get) == 0){
              ^   ^remove &
    
    每个strcmp()上都有类似的错误,因为
    buf
    get
    head
    都是特许数组

    (3)
    recv()
    不会终止读取缓冲区,因此最好在使用它之前添加null(
    \0
    )(我可以注意到,您使用buff作为字符串)

    你喜欢:

    bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
    buf[bytesRec] = '\0'
    
    infect您应该只读
    BUFSIZE-1
    字节,为空
    '\0'
    符号保留一个字节,如:

    ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0);
    buf[bytesRec] = '\0' 
    
    这只发送字符串,不包括终止NULL。接收缓冲区不在服务器端终止接收的字符串

    这就是为什么您仍然看到上一条消息中的“D”字符

    You want GETD <-- 'D' is from the previous 'HEAD'
    
    编辑:正如@Zan指出的,不要这样做:

    或者从客户端发送空终止符

    send(clientSocket, request, strlen(msg) + 1, 0);
    

    您可以删除问题中的重复代码并发布一些客户端代码吗?
    printf(“结果%s\n”,result);
    在服务器端打印什么?对不起,我再次测试了它,假设我发送了“GET aa bb”,它会打印“result GET”,“result aa”,result“bb”。这显然是一个进一步的问题,但即使只发送“得到”或“头”"结果在上述行为中,您是否发送了一个c样式的字符串,即以null结尾?您是否确实发送了null字符?即使您发送了,您似乎也没有遵循任何类型的协议来检查null是否已被实际接收-如果您发送了4个字符,“bytesRec”可能会返回为1、2、3或4。-您必须循环untl空值出现在缓冲区的某个地方,然后解析您的消息直到该空值。strcmp问题真的很重要吗?第二个问题是否会衰减为指针?@jsn您的意思是隐式typecase字可以在strcmp()中将
    char(*)[]
    转换为
    char*
    那么是的,你是对的。@jsn我认为strcmp问题很重要。它
    You want GETD <-- 'D' is from the previous 'HEAD'
    
    buf[bytesRec] = '\0';
    
    send(clientSocket, request, strlen(msg) + 1, 0);