【发布时间】:2010-02-02 06:51:35
【问题描述】:
下面是我遇到的套接字编程问题的代码片段。在 select 调用之后,如果我没有在第 9 行休眠,在 Windows XP 上,当我检查 xmlSize 时,在第 11 行收到 1 个字节(而不是从服务器发送 4 个字节作为整数) ,它被设置为 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 }
【问题讨论】:
-
你知道单次调用recv()接收的字节数不能保证单次调用send()发送的字节数吗?
-
好的,我现在看到了问题,但我没想到会出现这种行为,因为 recv 函数将字节数作为参数。那么你有什么建议呢?
-
该数字是最大字节数,因此请继续调用 recv() 并调整该数字,直到您读取了四个字节。