- 每一个TCP套接字有一个发送缓冲区,我们可以使用SO_SNDBUF套接字选项来更改该缓冲 区的大小
- 当某个应用进程调用write时,内核从该应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区。如果该套接字的发送缓冲区容不下该应用进程的所有数据(或 是应用进程的缓冲区大于套接字的发送缓冲区,或是套接字的发送缓冲区中已有其他数据),该应用进程将被投入睡眠。这里假设该套接字是阻塞的,它是通常的默认设置。内核将不从write系统调用返回,直到应用进程缓冲区中的所有数据都复制到套接字发送缓冲区。因此,从写一个TCP套接字的write调用成功返回仅仅表示我们可以重新使用原来的应用进程缓冲区,并不表明对端的TCP或应用进程已接收到数据。(我们将在讲解SO_LINGER套接字选项详细讨论这一点)
- 这一端的TCP提取套接字发送缓冲区中的数据并把它发送给对端TCP,其过程基于TCP数据 传送的所有规则(TCPv1的第19章和第20章)。对端TCP必须确认收到的数据,伴随来自对端的 ACK的不断到达,本端TCP至此才能从套接字发送缓冲区中丢弃已确认的数据。TCP必须为已 发送的数据保留一个副本,直到它被对端确认为止
- 本端TCP以MSS大小的或更小的块把数据传递给IP,同时给每个数据块安上一个TCP首部 以构成TCP分节,其中MSS或是由对端通告的值,或是536(若对端未发送一个MSS选项)。(536 是IPv4最小重组缓冲区字节数576减去IPv4首部字节数20和TCP首部字节数20的结果。)IP给每个 TCP分节安上一个IP首部以构成IP数据报,并按照其目的IP地址查找路由表项以确定外出接口, 然后把数据报传递给相应的数据链路。IP可能在把数据报传递给数据链路之前将其分片,不过 我们已经谈到MSS选项的目的之一就是试图避免分片,较新的实现还使用了路径MTU发现功 能。每个数据链路都有一个输出队列,如果该队列已满,那么新到的分组将被丢弃,并沿协议 栈向上返回一个错误:从数据链路到IP,再从IP到TCP。TCP将注意到这个错误,并在以后某个 时刻重传相应的分节。应用进程并不知道这种暂时的情况
相关文章: