TCP链接的建立与终止
包含 connect、accept和close三个函数,并使用netstart程序调试TCP应用。
建立TCP连接:需要三个分节
1、服务器必须准备好接受外来的链接,可调用socket、bind和listen三个函数完成,被动打开;
2、客户调用connect发起主动打开。客户TCP发送一个SYN(同步)分节,告诉服务器客户将在连接中发送的数据的初始序列号。通常SYN分节不携带数据,该IP数据报只包含有一个IP首部、一个TCP首部及可能有的TCP选项。
3、服务器必须确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,含有服务器将在同一个连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户的SYN的确认(ACK).
4、客户必须确认服务器的SYN。
每一个SYN可含有多个TCP选项,常用:
1、MSS选项。以太网上IPV4典型值1460。发送SYN的TCP一端告知对端他的最大分节大小即MSS,他在本链接的每个TCP分解中愿意接受的最大数据量。发送端TCP使用接收端的MSS值作为所发送分节的最大大小。TCP_MAXSEG套接字选项提取和设置该TCP选项。
2、窗口规模选项。使用SO_RCVBUF套接字选项影响该TCP选项。
3、时间戳选项。可防止由失而复得的分组可能造成的数据损坏。
TCP终止连接:需要4个分节。(橙色部分,总觉得书上说得太绕有歧义或是我自己理解得不好)
1、某应用进程首先调用close,该端主动关闭。该端TCP发送一FIN分节,表示数据发送完毕。
2、接受到该FIN的对端被动关闭。该FIN由TCP确认。它的接受也作为一个文件结束符(end-of-file)传递给应用进程(放在一排队等候该应用进程接受的任何其他数据之后),因为FIN的接受意味着接收端在相应链接上再无额外数据可接受。
3、一段时间后,接收到这个文件结束符的应用进程调用close关闭它的套接字。这将导致他的TCP也发送一个FIN。
4、接受该最终FIN的元发送端TCP确认该FIN。
通常四步,因为某些情形下,步骤一的FIN随数据一起发送;步骤二和步骤三发送的分解都出自执行被动反比的那一段,有可能合并成一个分节。
补充说明:
步骤2-3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,即半关闭。
当套接字关闭时,所在端TCP各自发送一个FIN,这是由应用进程调用close发生的。当一个Unix进程无论自愿(exit或main返回)还是非自愿(收到终止本进程信号)终止时,所有打开的描述符都被关闭,这也导致任然打开的任何TCP链接上发出一个FIN。
无论客户还是服务器,任何一段都可以执行主动关闭。通常情况是客户执行主动关闭。但某些协议,譬如HTTO/1.0由服务器执行主动关闭。
TCP状态转换图:tcp为一个链接定义了11种状态。
观察分组:
注意:服务器对客户请求的确认是伴随其应答发送的,该做法为捎带(piggybacking),他通常在服务器处理请求并产生应答的时间少于200ms时发生。如果耗时更长,经先确认再应答。
TIME_WAIT状态存在的两个理由:
1、可靠地实现TCP全双工连接的终止;假设最后一次ACK丢了来解释它,服务器将重新发送他的最终FIN,因此可恶必须维护状态信息,允许它重发最终ACK。客户端不得不准备好重传最终那个ACK。
2、允许老的重复分节在网络中消逝;两个IP和端口头一次建立连接后,下一次又建立了新的连接。后一个连接为前一个连接的化身,因为他们的IP地址和端口号都相同。TCP必须防止老的重复分组在该链接已终止后再出现被误解为属于同一连接的信息。所以,TCP将不给出于TIME_WAIT状态的链接发起新的化身。TIME_WAIT状态的持续时间是MSL的2倍,这足以让某个方向上的分组最多存活MSL秒后被丢弃,另一个方向上的应答最多存活MSL秒后也被丢弃。、
常见协议使用的协议情况: