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 ...