来自:
socket编程缓冲区大小对send()的影响_wangst4321的专栏-CSDN博客
TCP/UDP的接收缓冲区和发送缓冲区_Swallow_he的博客-CSDN博客
socket之send与发送缓冲区大小的关系_水果刀的专栏-CSDN博客
文章目录
每个TCP socket在内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式以及TCP的流量/拥塞控制便是依赖于这两个独立的缓冲区以及缓冲区的填充状态。
接收缓冲区
接收缓冲区把数据缓存到内核,应用进程一直没有调用recv()
进行读取的话,此数据会一直缓存在相应socket的接收缓冲区内。不管进程是否调用recv()
读取socket,对端发来的数据都会经由内核接收并且缓存到socket的内核接收缓冲区之中。
recv():把内核缓冲区中的数据拷贝到应用层用户的buffer里面,并返回。
发送缓冲区
进程调用send()
发送的数据的时候,最简单情况(也是一般情况),将数据拷贝进入socket的内核(拷贝到内核就返回)发送缓冲区之中,然后send
便会返回。recv()换句话说,send()
返回之时,数据不一定会发送到对端去(和write写文件有点类似),只是完成了拷贝动作而已。
recv()send():仅仅是把应用层缓冲区的数据拷贝进socket的内核发送缓冲区中(send()只负责拷贝,拷贝到内核就返回),发送是TCP的事情,和send()其实没有太大关系。
数据发送和接收的过程:
tcp、udp接收缓冲区的不同
接收缓冲区被TCP和UDP用来缓存网络上来的数据,一直保存到上层应用进程读走为止。
对于TCP
如果应用进程一直没有读取,接收缓冲区满了之后,发生的动作是:接收端通知发送端,接收窗口关闭(win=0),这便是滑动窗口的实现。保证TCP套接口接收缓冲区不会溢出,从而保证了TCP是可靠传输。因为对方不允许发出超过所通告窗口大小的数据。
recv()如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方TCP将丢弃它。
查看测试机的socket发送缓冲区大小:
cat /proc/sys/net/ipv4/tcp_wmem
第一个值是一个限制值,socket发送缓存区的最少字节数;
第二个值是默认值;
第三个值是一个限制值,socket发送缓存区的最大字节数;
根据实际测试,发送缓冲区的尺寸在默认情况下的全局设置是16384字节,即16k。
对于udp
recv()每个UDP socket都有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发(尽最大能力交付),不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。
当套接口接收缓冲区满时,新来的数据报无法进入接收缓冲区,此数据报就被丢弃。UDP是没有流量控制的;快的发送者可以很容易地就淹没慢的接收者,导致接收方的UDP丢弃数据报。
缓冲区大小对send()的影响
Socket编程中,使用send()传送数据时,返回结果受到以下几个因素的影响:
- Blocking模式或non-blocking模式
- 发送缓冲区的大小
- 接收窗口大小
send函数在发送的数据长度大于发送缓冲区大小,或者大于发送缓冲区剩余大小时,socket会怎么反应
socket之send与发送缓冲区大小的关系_水果刀的专栏-CSDN博客
recv()当send的数据长度大于socket的缓冲区长度时,不管是windows还是linux,阻塞还是非阻塞,send都会分帧发送,分帧到缓冲区能够接收的大小