2010-06-16 65 views

回答

6

您可以使用setsockoptSO_SNDBUFSO_RCVBUF)更改每個套接字連接的讀取和寫入緩衝區。

默認和最大尺寸取決於平臺。另外,如果你爲每個單獨的讀取提供更大的用戶側緩衝器,例如,與recv

如果您按順序使用多個recv s,您可以通過連接讀取無限量的字節,它只會花費無限的時間。

+0

+1直接點答案 – INS 2010-06-16 11:03:50

+1

對於unix域套接字,SO_RCVBUF對Linux沒有影響。但SO_SNDBUF可用於調整發送緩衝區,但套接字發送緩衝區仍受net.core.wmem_max值的限制。 http://man7.org/linux/man-pages/man7/unix.7.html。 – anbhat 2017-09-15 15:35:37

0

套接字的行爲是實現的依賴。一般來說,當你發送()時,不能保證有多少字節會被壓入套接字。由於內核控制它,它可以是任何數字,通常在1500或更小的範圍內。所以你必須做的是檢查send()返回碼,並保持將數據壓入套接字,直到完成。這個例子假定您已經設置了插座無阻塞:

fcntl(s, F_SETFL, O_NONBLOCK); 


int sendall(int s, char *buf, int *len) 
{ 
     int total = 0;  /* how many bytes we've sent */ 
     int bytesleft = *len; /* how many we have left to send */ 
     int n=0; 
     int retries=0; 
     struct timespec tp={0,500}; 

     while(total < *len) 
     { 
       n = send(s, buf+total, bytesleft, 0); 
       if (n == -1) 
       { 
        /* handle errors here, 
         plus check for EWOULDBLOCK 
         and then nanosleep() 
        */ 
       } 
       total += n; 
       bytesleft -= n; 
     } 

要回答你的問題 - 沒有沒有任何限制,你不能用一個發送()調用發送您的所有數據。

+0

爲什麼將它設置爲非阻塞,然後在緊密的循環中迭代它?似乎是一個矛盾。 – Will 2010-06-16 11:27:03

+0

請注意EWOULDBLOCK註釋和timepsec聲明。這意味着在少量時間內等待阻塞套接字。 我沒有表現出來,你是正確的,但並不是絕對不打算成爲緊密循環。我拋棄了40行函數將它放在這裏。很大程度上是因爲它有一些Solaris特定的套接字代碼。發佈系統特定的代碼是IMO的錯誤想法,除非明確要求將其作爲問題的一部分。 – 2010-06-16 11:51:09

+1

嗯,你錯了** a)** 1500字節 - 你假設以太網數據包的大小,但它實際上是socket *發送緩衝區*,當你調用send(2)但通常大於一幀(並且在計算中忘記IP和TCP或UDP標頭); ** b)**非阻塞和nanosleep - 您只是模擬阻塞發送,但不會讓發送緩衝區空間變爲可用時喚醒您。 *擺脫此代碼*,並在Solaris上使用'/ dev/poll'。 – 2010-06-17 02:30:14