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

时间:2013-04-01 16:34:17

标签: c sockets

我对socket编程很新,我遇到了麻烦。我想实现一个服务器,根据某个客户端请求回答。在我的情况下,GET,HEAD或其他错误。请考虑以下代码

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

  1. GET
  2. HEAD
  3. GET
  4. 测试
  5. GET
  6. ,从客户端打印的答案是

    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;
    }
    

    和客户端

    #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;
    }
    

2 个答案:

答案 0 :(得分:5)

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

这只发送字符串字符,不包括终止NULL。接收缓冲区不会终止服务器端收到的字符串。

这就是为什么你仍然看到上一条消息中的'D'字符。

You want GETD <-- 'D' is from the previous 'HEAD'

终止服务器上收到的字符串,

buf[bytesRec] = '\0';

编辑:正如@Zan指出的那样,不要这样做:

或从客户端发送NULL终止符。

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

答案 1 :(得分:2)

你的strcmp() in if错误

(1)而不是buf您需要与result进行比较,因为我可以从您的问题中了解到,请执行以下操作:(您在评论中说,结果打印为GET)

if(strcmp(result, get) == 0){

(2)正如@phihag所回答的应该是

if(strcmp(buf, get) == 0){
          ^   ^remove &

你在每个strcmp()上都有类似的错误,因为bufgethead都是包机数组。

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

喜欢:

bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
buf[bytesRec] = '\0'

感染您应该只读取BUFSIZE-1个字节,其中一个字符为空'\0'符号,如:

ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0);
buf[bytesRec] = '\0'