首先了解的TCP协议的报文格式,网上和书本上都有很多介绍,我们只要知道它包含了以下几个重要字段
一:源端口号和目标端口号 (16bits),需要注意的是源和目标ip地址不在TCP报文中,而是在IP报文中
二:序号和确认序号(32bits),序号用来标识从TCP端发送的数据字节流,表示在这个报文中的第几个数据字节;
确认序号包含发送确认的一端所期望收到的下一个序号。因此,确认序号应当是上次已成功收到的数据字节序号加1。
三:6bits的标志比特,其中重要且经常用到的是:
ACK:确认序号有效
SYN:同步序号发起一个连接
FIN :发端完成发送任务
RST :重建连接
还有其他的字段就不多说了。
TCP连接建立与终止:
建立:三次握手
客户:调用connect发起主动连接,发送带SYN标志的TCP报文,套接字由CLOSED状态变成SYN_SENT状态
服务器:通过socket,bind,listen后进入LISTEN状态,调用accept等待客户连接;收到客户的SYN后,返回带SYN和ACK报文,进入SYN_REVC状态
客户:收到从服务器返回的SYN和ACK后,从connect成功返回,进入ESTABLISHED状态,并返回ACK
服务器:收到客户的ACK后,从accept成功返回,进入ESTABLISHED状态
以上是完成三次握手后,成功建立连接的过程。当然也会由失败的情况。
终止:四次握手
终止可以由服务器发起,但通常是由客户发起的,这里以客户发起说明
客户:调用close,发送带FIN的TCP报文,进入FIN_WAIT1状态;
服务器:收到FIN后,进入CLOSED_WAIT状态,并且read返回0;并向客户端发送ACK确认这个FIN
客户:收到FIN的ACK后进入FIN_WAIT2状态;
服务器:完成必要的工作后调用close,发送FIN,进入LAST_ACK状态;
客户:收到FIN后,进入TIME_WAIT状态,发送ACK到服务器,并经过2MSL时间后,进入CLOSED状态。
服务器:收到ACK后,立即进入CLOSED状态
成功完成四次握手(虽然文字描述看起来不止4次),连接终止。
一些必要的特性:
MTU(Maximum Transmission Unit) : 最大传输单元,一般以太网为1500字节
MSS(Maximum segment size) : 最大分节大小,用于向对端TCP通告对端在每个分节中能发送的最大TCP数据量,通常设成MSS = MTU - SIZEO(IP首部 + TCP首部),
MSL(Maximum segment lfetime) : 最大分节生命。指任何IP数据报文在因特网中的存活最长时间,而不是跳数。
TCP输出:
每个TCP套接字都有一个发送缓冲区,可用SO_SNDBUFL套接字选项来更改该缓冲去大小。
内核从该应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区。如果剩余的发送缓冲区不能容纳所有的进程发送数据,在阻塞的情况下,该进程将进入睡眠即阻塞在write中,直至有足够的发送缓冲区间才从write返回。所以写一个TCP套接字的write成功调用仅代表写进了发送缓冲区间,而对端不一定收到了数据。
对端TCP必须确认收到的数据,伴随着ACK的不断到达,本端TCP至此才能将套接字发送缓冲区中丢弃已确认的数据。