[英]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,那么您不能使用這些特定字節來分隔消息,有兩種經典方法:
另一種方法是顯式地編碼流本身中每條消息的長度,最好作為前綴,以便您知道預期的數據量。
請參閱另一個SO問題以獲得答案和代碼示例:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.