window中,socket send()函数可发6M一张的图片,可是同样的代码移植到Linux中就出问题,原因是这个的默认buffer不一样。
以下是Linxu中的socket的相关信息:
1、从socket里一次最大读取字节数取决于接收buffer的大小,亦即socket的SO_RCVBUF对应的数值的2倍,这个2倍关系是内核决定的。 2、所以关键在于SO_RCVBUF的大小了。SO_RCVBUF大小,每个系统可能不一样,比如我使用linux,rmem_max存储了它的最大值: [root@localhost sockopt]# cat /proc/sys/net/core/rmem_max 124928 3、所以对于我这台电脑,最大接收buffer是124928*2的大小,也就是说最大允许一次读取124928*2大小了。 ====================================================================== 以下是linux对该buffer的描述 SO_RCVBUF Sets or gets the maximum socket receive buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using set- sockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/rmem_default file, and the maximum allowed value is set by the /proc/sys/net/core/rmem_max file. The minimum (doubled) value for this option is 256. ======================================================================
利用 int snd_size = 0; /* 发送缓冲区大小 */ int rcv_size = 0; /* 接收缓冲区大小 */ socklen_t optlen; /* 选项值长度 */
optlen = sizeof(snd_size); err = getsockopt(s, SOL_SOCKET, SO_SNDBUF,&snd_size, &optlen); if(err<0){ printf("获取发送缓冲区大小错误\n"); }
optlen = sizeof(rcv_size); err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcv_size, &optlen); if(err<0){ printf("获取接收缓冲区大小错误\n"); } printf(" 发送缓冲区原始大小为: %d 字节\n",snd_size); printf(" 接收缓冲区原始大小为: %d 字节\n",rcv_size);
获取发送和接收buffer的大小。
-----------------------------------------------------------------------------
设置 socket通信时的buffer大小
获取系统的最大buffer cat /proc/sys/net/core/rmem_max
snd_size = 10*1024; /* 发送缓冲区大小为8K */ optlen = sizeof(snd_size); err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &snd_size, optlen); if(err<0){ printf("设置发送缓冲区大小错误\n"); }
/* * 设置接收缓冲区大小 */ rcv_size = 10*1024; /* 接收缓冲区大小为8K */ optlen = sizeof(rcv_size); err = setsockopt(s,SOL_SOCKET,SO_RCVBUF, (char *)&rcv_size, optlen); if(err<0){ printf("设置接收缓冲区大小错误\n"); }
实际缓冲区的大小为设置缓冲区大小的两倍,这个一定要注意
////////////=================================================================================////////
socket send buffer(user malloc)========>内核buffer(TCP 收发Buffer)------------------>socket reciver buffer(uer malloc)
其中 socket send buffer(user malloc) 发送到 内核buffer时,发送一次就行了。
内核buffer到socket reciver buffer时,由于内核buffer有限,每次只能提取一部分,所以可以用while循环好几次。【send只需一次即可】