socket之send與傳送區的大小關係

2021-07-03 10:35:41 字數 4244 閱讀 1983

socket之send與傳送緩衝區大小的關係

收藏人:sven_

2013-09-13 | 閱:3917

**17

| **

|  分享

關於send函式在傳送的資料長度大於傳送緩衝區大小,或者大於傳送緩衝區剩餘大小時,socket會怎麼反應。參見這篇部落格的兩種說法

自己做了個測試,伺服器只起socket在偵聽,不recv, 也不send.

[cpp]view plain

copy

32bit  

#include 

#include 

#include 

#include 

int main(void)    

客戶端,將傳送緩衝區大小設定成2k,然後一次傳送3k的資料。

[cpp]view plain

copy

32bit  

#include 

#include 

#include 

#include 

#include 

#include 

int main()    

互動報文

從這裡看出當傳送長度大於緩衝區大小時,是分次傳送,三次加起來 1448 + 1448 + 176 = 3072

在windows下,做同樣的測試

[cpp]view plain

copy

// xp vc6.0 32bit  

#include 

#include 

#include 

#pragma  comment (lib,"ws2_32")  

void  main()  

optlen = sizeof(optval);  

getsockopt(connectsocket, sol_socket, so_sndbuf, (char*)&optval, &optlen);  

printf("send buf len is %d\n",optval);           //預設傳送緩衝區8k  

getsockopt(connectsocket, sol_socket, so_rcvbuf, (char*)&optval, &optlen);  

printf("recv buf len is %d\n",optval);          //預設接收緩衝區8k  

optval = 1024 * 2;  

setsockopt(connectsocket, sol_socket, so_sndbuf, (char*)&optval, optlen);  

getsockopt(connectsocket, sol_socket, so_sndbuf, (char*)&optval, &optlen);  

printf("send buf len change to %d\n",optval);  

// 設定服務端的通訊協議、ip位址、埠  

clientservice.sin_family = af_inet;  

clientservice.sin_addr.s_addr = inet_addr( "222.111.112.204" );  

clientservice.sin_port = htons( 103 );  

// 連線到服務端  

if ( connect(  

connectsocket, // socket  

(sockaddr*) &clientservice, // 位址  

sizeof(clientservice) // 位址的大小  

) == socket_error)  

len = send(connectsocket, (char*)buf, 1024*3, 0);  

printf("send length is %d\n",len);             //這裡同樣直接返回3072  

system("pause");  

return;   

}  

抓取報文

分三次傳送1460+1460+152 = 3072

上面都是阻塞的傳送,對於socket是非阻塞的話,做同樣的測試

[cpp]view plain

copy

32bit  

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

int main()  

else  

else  

}     

}  if (-1 ==(sendlen = send(fd,buf,1024*3,0)))  

else  

return 0;  

}  

和blocking socket表現是一樣的,一次send,協議棧分三幀傳送。

[cpp]view plain

copy

//xp vc6.0 32bit  

#include 

#include 

#include 

#pragma  comment (lib,"ws2_32")  

void  main()  

if(0 == ioctlsocket(connectsocket, fionbio, (unsigned long *)&on))  

optlen = sizeof(optval);  

getsockopt(connectsocket, sol_socket, so_sndbuf, (char*)&optval, &optlen);  

printf("send buf len is %d\n",optval);  

getsockopt(connectsocket, sol_socket, so_rcvbuf, (char*)&optval, &optlen);  

printf("recv buf len is %d\n",optval);  

optval = 1024 * 2;  

setsockopt(connectsocket, sol_socket, so_sndbuf, (char*)&optval, optlen);  

getsockopt(connectsocket, sol_socket, so_sndbuf, (char*)&optval, &optlen);  

printf("send buf len change to %d\n",optval);  

// 設定服務端的通訊協議、ip位址、埠  

clientservice.sin_family = af_inet;  

clientservice.sin_addr.s_addr = inet_addr( "222.111.112.204" );  

clientservice.sin_port = htons( 103 );  

// 連線到服務端  

if ( connect(  

connectsocket, // socket  

(sockaddr*) &clientservice, // 位址  

sizeof(clientservice) // 位址的大小  

) == socket_error)  

else  

else  

}  }   

else  

}             

if (socket_error == (len=send(connectsocket, (char*)buf, 1024*3, 0)))  

else  

system("pause");  

return;   

}  

可見,當send的資料長度大於socket的緩衝區長度時,不管是windows還是linux,send都會分幀傳送。

SOCKET之Send和Recv理解

int send socket s,const char buf,int len,int flags 引數描述 同步 socket 的send函式的執行流程如下 如果len大於傳送緩衝區剩餘空間大小 不足放入剩餘傳送緩衝區 send就一直 等待協議把s傳送緩衝區中的資料傳送完 如果len小於傳送緩衝...

socket之send和recv原理剖析

當建立乙個tcp scoket 物件的時候會有乙個傳送緩衝區和接收緩衝區,這個傳送和接受快取區指的就是記憶體中的一片空間 send是不是直接把資料發給伺服器?不是,要想傳送資料必須通過網絡卡傳送資料,應用程式是無法直接通過網絡卡傳送資料的,他需要呼叫作業系統介面,也就是說,應用程式把資料先寫入到快取...

socket 接收和傳送緩衝區

問題產生 在進行客戶端向服務端傳送資料時,每次傳送一定數量資料後傳送端就等不到send函式的返回,導致程式一直卡死在send函式。通過抓包發現 傳送端傳送過快而接收端處理速度過慢,導致快速傳送一定量資料後wireshark顯示傳送端傳送資料有window full提醒,幾次之後接收端會傳送zero ...