我不太清楚TCP和套接字的一些详细机制。
一个客户端通过TCP连接到服务器,并向服务器发送数据。如果发送的速度远远大于处理的速度会发生什么?例如,如果客户端每秒发送1MiB,但服务器每秒只能处理1kib,这会导致系统内存崩溃吗?
我知道在套接字API中有接收缓冲区大小设置:
- 如果我设置缓冲区大小,但数据溢出怎么办?
- 如果我不设置接收缓冲区大小怎么办?
简而言之,当服务器每秒只能处理1k时,客户端将没有机会每秒发送1M。这有两个原因:
- TCP有慢启动机制
- TCP有一个窗口机制,TCP连接的每一端都在不断地向另一端发布自己的接收能力。
如果客户端发送的数据超过了指定的窗口大小,这是没有意义的,因为服务器会首先删除超出窗口大小的数据段,所以如果客户端忽略窗口大小,就必须重新发送。
缓冲区位于不同的层中。你可以通过套接字选项设置的缓冲区是套接字级别的缓冲区,它们不能直接控制TCP窗口的大小。如果您不设置这些缓冲区,您将在套接字级别获得默认缓冲区大小。TCP正在排队,这取决于是否接收到窗口大小中的无序数据包。如果它接收到的数据是有序的,它触发套接字级别,然后数据才被推入套接字级别缓冲区,然后只有在有可用空间的情况下才会被推入。如果TCP不能推送它在套接字缓冲区上接收到的所有数据,那么这将影响计算TCP窗口大小的算法。此计算机制基于TCP缓冲区中剩余的字节数。
没有人会崩溃,无论是服务器还是客户端。
在客户端,一个可以高速发送的,类似的事情发生了,因为TCP将根据服务器的广告窗口大小看到它不能在线路上放置太多数据。因此客户端发送缓冲区将被填满。如果已满,客户端套接字要么在发送模式下阻塞(阻塞模式),要么返回一个错误指示它将阻塞(非阻塞模式)。
所以这不仅仅说明发生了什么,我还试图解释为什么会发生这些事情以及如何实现。
如果发送的速度远远大于处理的速度会发生什么?例如,客户端每秒发送1 MiB,而服务器每秒只能处理1 KiB…
如果发送方处于阻塞模式,如果它走在接收方前面太远,它将阻塞。
如果处于非阻塞模式,send()
将返回-1,errno == EAGAIN/EWOULDBLOCK.
号会导致系统内存崩溃吗?
我知道在套接字API中有接收缓冲区大小设置:
- 如果我设置缓冲区大小,但数据溢出怎么办?
当接收缓冲区已满时,接收主机将通知发送方停止发送。
- 如果我不设置接收缓冲区大小怎么办?
你会得到一个默认的大小
网络层有拥塞控制算法来控制这些情况:-
- 分组队列和服务策略
- 丢包策略等
在传输层(TCP),使用某些策略来消除这种情况:-
- <
- 重发政策/gh>
- 流量控制策略(在这里您将了解TCP中的滑动窗口协议来控制数据流)
- 超时决心等。
根据上述因素,如调整/滑动窗口(在传输层)、抖动控制、减载(在网络层)等,如果:
(i)网络/路由器被请求淹没,或者(ii)数据流在传输层(TCP)的两个进程之间是不规则和错误的。