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

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

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

  1. 得到
  2. 得到
  3. 测试
  4. 得到

,从客户端打印的答案是

 You want GET You want HEAD You want GETD HTTP/1.1 400 Bad Request You want GET Bad Request 

因此,似乎从服务器发送的消息有点“覆盖”,但这怎么可以避免呢? 是否可以“清除服务器缓冲区”,如果这是问题呢?

这是完整的服务器端代码

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

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

你的strcmp()如果错了

(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'