* TCP作为运输层服务,和UDP最大的不同是它是一种面向连接的、可靠的字节流服务。大多数的互联网应用程序都使用TCP,如http,ftp,telnet,smtp等。
面向连接是指使用TCP某个应用的两端在交互数据前必须先建立一个TCP连接。
TCP的可靠性主要由以下方式体现:
1. 分割应用数据为TCP认为最适合发送的块,称为报文段;
2. TCP使用定时器以等待目的端对报文段的接收确认;
3. TCP收到对方端的一个报文段后,会给对方发送一个接收确认;
4. 通过校验和确认数据差错,若校验错误,丢弃数据,不发送接收确认;
5. 把数据交给应用层前,对各报文段重新排序组织;
6. 丢弃重复发送的数据;
7. 流量控制,通过缓冲区实现。
TCP传输稳定的字节流,但不关心字节流数据类型是ASCII还是二进制。
TCP采用全双工通信。
* TCP的首部(20个固定字节+选项):
16位源端口--16位目的端口--32位起始序号--32位确认序号--
4位首部长度--6位保留位(置0)--6位标志位--16位窗口大小--16位校验和--16位紧急指针--
选项
32位起始序号表示本报文段在第几个字节开始发送;
在tcpdump的输出中还包括了下一个待发送的报文段的起始序号,
32位确认序号表示待接收的下一个报文段起始序号,即被确认的报文段的起始序号加上报文段长度,ACK标志位置位时有效;
标志位从高到低依次为:
URG: 紧急指针有效;
ACK: 确认位;
PSH: 通知接收方应马上把缓冲区接收到的全部数据递交给应用层的进程,而不再等待其它额外的数据,对这个标志的确认,窗口一般恢复到最大;
RST: 连接复位,在异常状况下置位,例如端口不可达或者连接异常终止(如在telnet时用^D或者^C强行关闭程序);
SYN: 同步方式,用于建立连接;
FIN: 连接结束;
窗口用于流量控制,通知对方自己的缓冲区当前剩余情况;
校验和覆盖整个TCP报文段,包括首部和数据部分,采用算法与UDP类似,使用伪首部;
紧急指针在URG被置位时使用,它指向紧急数据的最后一个字节。
MSS(maximum segment size最大段长度)是较常用的TCP首部选项,用于管理每个TCP包的长度;其它可能的选项还包括窗口扩大因子、时间戳等。
* TCP连接由4个元素唯一确定:源IP、源TCP端口、目的IP、目的TCP端口。
* TCP的状态变迁
按照netstat的显示有以下的TCP状态:
CLOSED, LISTEN, SYN_RCVD, SYN_SENT, ESTABLISHED,
CLOSE_WAIT, LAST_ACK, FIN_WAIT_1, CLOSING, FIN_WAIT_2, TIME_WAIT
其中进入ESTABLISHED状态对应一个连接的建立,退出ESTABLISHED对应一个连接的终止;
TIME_WAIT的等待时间为2MSL,即最大段生存时间,因为连接终止前发起的一方可能需要重发ACK,所以停留在该状态的时间必须为MSL的2倍。
* TCP的建立
TCP的建立通过客户端与服务器端的三次握手实现。
1. 客户端发出含SYN位的报文段,并指出要求连接的TCP端口和初始序号,同时更改状态为SYN_SENT;
2. 处于LISTEN状态的服务器作出响应,发送SYN和ACK,并给出确认序号,同时更改状态为SYN_RCVD;
3. 客户端确认服务器的响应,给出带确认序号的ACK段,同时更改状态为ESTABLISHED,服务器收到该响应后也更改状态为ESTABLISHED。
* TCP的终止
TCP的终止通过双方的四次握手实现。发起终止的一方执行主动关闭,响应的另一方执行被动关闭。
1. 发起方更改状态为FIN_WAIT_1,关闭应用程序进程,发出一个TCP的FIN段;
2. 接收方收到FIN段,返回一个带确认序号的ACK,同时向自己对应的进程发送一个文件结束符EOF,同时更改状态为CLOSE_WAIT,发起方接到ACK后状态更改为FIN_WAIT_2;
3. 接收方关闭应用程序进程,更改状态为LAST_ACK,并向对方发出一个TCP的FIN段;
4. 发起方接到FIN后状态更改为TIME_WAIT,并发出这个FIN的ACK确认。ACK发送成功后(2MSL内)双方TCP状态变为CLOSED。
* TCP的半关闭
指结束一方的数据传送,同时继续接收对方的数据。
* TCP的半打开
一方连接关闭,另一方不知道。例如运行telnet的客户端断线或者意外停电,而在服务器上的这个连接还是打开的。
* TCP的同时打开和同时关闭
同时打开需要双方确认对方的本地端口,
同时打开和同时关闭双方都是主动打开和主动关闭,而且需要几乎同时开始启动至少在收到对方的SYN或者FIN前就启动;
同时打开和同时关闭的握手过程和状态变迁略。
* TCP服务器的设计:
一个服务器的任何进程都只能使用同一个TCP端口,但是允许使用不同接口(IP)。
对于同一端口的多个连接请求使用连接队列处理,处理原则为FIFO,被TCP处理的连接在缓冲区中处理其命令或者数据传输。
阅读(1940) | 评论(0) | 转发(0) |