2

下面是我遇到的套接字编程问题的代码片段。在选择调用之后,如果我没有在第 9 行休眠,在 Windows XP 上,第 11 行接收到 1 个字节(而不是从服务器发送 4 个字节作为整数),当我检查 xmlSize 时,它​​设置为 0。因为 iResult 为 1,所以继续执行并在第 15 行第二次接收调用时使用 xmlSize=0,并且 iResult 设置为 0,之后因为 iResult=0 连接被关闭。

但是在 Windows 7 上这并没有发生,程序愉快地读取了 4 个字节并继续正常执行。但是在 XP 上,我睡了(我只是编造的)并且它起作用了,但是为什么?

这段代码有什么缺陷?

1   while(is_running())
2   {
3       FD_ZERO(&readfds);
4       FD_SET(server_socket, &readfds);
5       iResult = select(server_socket+1, &readfds, NULL, NULL, &tv);
6       if  (!(iResult != SOCKET_ERROR && FD_ISSET(server_socket, &readfds) )) {
7           continue;
8       }
9       Sleep(500); // This Sleep is not required on Windows 7, but is required on 10 XP but WHY? 
11      iResult = recv(server_socket, (char *)&xmlSize, sizeof(xmlSize), 0);
12      xmlSize = htonl(xmlSize);
13      if ( iResult > 0 ){
13          printf("Bytes received: %d, XML Size:%d", iResult, xmlSize);
14          
15          iResult = recv(server_socket, xml, xmlSize, 0);
16          if ( iResult > 0 ){
17              xml[xmlSize] = '\0';
18              printf("Bytes received: %d", iResult);              
19              operation_connection(xml);
20          }
21          else if ( iResult == 0 ){
22              printf(LL_INTERR, CLOG("Connection closed"));
23              break;
24          }
25          else{
26              printf("recv failed with error: %d", WSAGetLastError());
27              break;
28          }
29      }
30      else if ( iResult == 0 ){
31          printf(LL_INTERR, CLOG("Connection closed"));   
32          break;
33      }
34      else{
35          printf("recv failed with error: %d", WSAGetLastError());
36          break;
37      }
38  }
4

2 回答 2

7

如果这是一个 TCP 套接字,你不应该关心。套接字传递一个,它不以任何方式或方式对应于write()另一端的原始 s 的大小。

它可以将一兆字节作为一百万个 1 字节read(),或作为单个 1MB 或两者之间的任何组合提供。

如果您依赖于 TCP 连接所传递的数据“块”的大小,那么您做错了。

如果您需要某种消息分隔符,那么在您的协议中明确设计一个,例如 HTTP 使用回车+换行的方式。如果您的协议是 ASCII,因此您不能使用这些特定字节来分隔消息,则有两种经典方法:

另一种方法是在流本身中显式编码每条消息的长度,最好作为前缀,这样您就知道需要多少数据。

于 2010-02-01T11:42:30.747 回答
3

请参阅this other SO question以获取答案和代码示例:

从套接字读取:是否保证至少获得 x 个字节?

于 2010-02-01T12:08:15.870 回答