繁体   English   中英

c ++套接字选择和接收问题

[英]c++ Socket select and receive problem

下面是我遇到套接字编程问题的代码片段。 选择调用之后,如果我没有在第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  }

如果这是一个TCP套接字,你不应该在乎。 套接字传递一个 ,它不会以任何方式或方式与原始write() s的大小相对应。

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

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

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

  • 使用其他字节序列,也许是ASCII 0x1E,“记录分隔符”。
  • 当它们包含在消息中时, 转义 CR + LF,使“普通”的CR + LF作为分隔符。 如果您的协议“希望”成为文本,这将是更好的解决方案。

另一种方法是显式地编码流本身中每条消息的长度,最好作为前缀,以便您知道预期的数据量。

请参阅另一个SO问题以获得答案和代码示例:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM