[英]c++ Socket select and receive problem
Below is the code fragment I have issue with socket programing. 下面是我遇到套接字编程问题的代码片段。 Here after select call, If I do not put a sleep on line 9, on Windows XP, 1 byte is received on line 11 (instead 4 byte is sent from server as integer), when I check xmlSize, it is set to 0. Because iResult is 1, execution continues and on line 15 second receive is called with xmlSize=0, and iResult is set to 0 and afterwards because iResult=0 connection is closed.
在选择调用之后,如果我没有在第9行上睡眠,在Windows XP上,第11行接收到1个字节(而不是从服务器发送4个字节作为整数),当我检查xmlSize时,它被设置为0。因为iResult是1,所以执行继续,并且在第15行第二次接收被调用xmlSize = 0,并且iResult被设置为0,之后因为iResult = 0连接被关闭。
But on Windows 7 this did not happen, program happily read 4 bytes and continued normal execution. 但是在Windows 7上没有发生这种情况,程序很乐意读取4个字节并继续正常执行。 On XP however I put a sleep(I just made this up) and it worked, but Why??
然而在XP上,我睡了一觉(我刚刚做了这个)并且它有效,但为什么?
What is the flaw in this code? 这段代码的缺陷是什么?
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 }
If this is a TCP socket, you shouldn't care. 如果这是一个TCP套接字,你不应该在乎。 The socket delivers a stream , it's doesn't correspond in any way or fashion to the size of the original
write()
s to the other end. 套接字传递一个流 ,它不会以任何方式或方式与原始
write()
s的大小相对应。
It could deliver a megabyte as one million 1-byte read()
s, or as a single 1MB one, or any combination in between. 它可以提供一兆字节作为一百万个1字节
read()
,或者作为单个1MB一个,或两者之间的任意组合。
If you depend on the size of the delivered data "chunks" for a TCP connection, you're doing it wrong. 如果您依赖于TCP连接的传递数据“块”的大小,那么您做错了。
If you need some kind of message separator, then explicitly design one into your protocol, the way carriage return+linefeed is used by eg HTTP. 如果你需要某种消息分隔符,那么在你的协议中明确地设计一个,例如HTTP使用回车+换行的方式。 If your protocol is ASCII so you can't use these particular bytes to separate messages, there are of two two classic approaches:
如果您的协议是ASCII,那么您不能使用这些特定字节来分隔消息,有两种经典方法:
Another approach is to explicitly encode the length of each message in the stream itself, preferably as a prefix so you know how much data to expect. 另一种方法是显式地编码流本身中每条消息的长度,最好作为前缀,以便您知道预期的数据量。
See this other SO question for an answer and code example: 请参阅另一个SO问题以获得答案和代码示例:
Read from socket: Is it guaranteed to at least get x bytes? 从套接字读取:是否保证至少获得x个字节?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.