簡體   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