2013-01-18 56 views
2

爲什麼send()winsock保證傳送您請求的所有字節?send()不傳遞所有字節?

這是TCP,它是阻塞套接字。

同樣,這種情況發生在非阻塞時。你怎麼能保證你發送的一切?

我注意到recv()也是這麼做的。

回答

7

如果它沒有發送任何東西,請在其餘的地方再次調用send。如果阻塞,您可以立即執行。如果非阻塞,您可以等待或使用套接字發現方法(如select或I/O完成端口)。 recv也是如此。如果你沒有得到你想要的,請再次致電recv。這是recvsend返回發送或接收的字節數的原因之一。

您傳遞給sendrecv的字節數只是一個限制。它可以發送比這更少的(儘管,除非非阻塞,通常不會)。但它肯定會收到比這少的。 (操作系統無法控制接收的數據量或收到的數據量。)

TCP是爲您實施的。但是如果你有一個涉及應用程序級消息的應用程序協議,那麼應用程序必須實現它們。它不會發生魔法。 TCP不會「將字節粘合在一起」成爲一條消息。 TCP是一種字節流協議,不是消息協議。如果你想要消息,你必須實現它們。

+0

大衛,稍OT但沒有我們comp.protocols.tcp-IP幾年前討論,實際上它併發送/緩衝阻塞模式下的所有字節?在所有已知的平臺上? – EJP

+0

@EJP:對於TCP,除非被信號中斷或發生錯誤,否則我所知道的每個實現都至少會將您在阻塞模式下傳遞給'send'的所有字節排隊,並且不會返回少於您請求的字節數它發送。 (這並不意味着一個實現不會在下週推出,但是可能很多現有代碼會在該實現中斷裂。) –

0

send告訴你它能夠通過它的返回值發送什麼。 循環直到send累積發送所有數據或返回錯誤。

5

此行爲是「按設計」。

您可以使用外循環,如圖所示:

int sendBuffer (SOCKET ClientSocket, const char *buf, int len, int flags) 
    { 
    int num_left = len; 
    int num_sent; 
    int err = 0; 
    const char *cp = buf; 

    while (num_left > 0) 
     { 
     num_sent = send(ClientSocket, cp, num_left, flags); 

     if (num_sent < 0) 
      { 
      err = SOCKET_ERROR; 
      break; 
      } 

     assert(num_sent <= num_left); 

     num_left -= num_sent; 
     cp += num_sent; 
     } 

    return (err == SOCKET_ERROR ? SOCKET_ERROR : len); 
    } 
+1

發送的0個字節並不表示連接已終止。 –

+0

@LittleHelper:是的,你說得對!糾正。 –