TCP数据报格式

(1)序号(sequence number):Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。初始时序号会被设置一个随机的初始值(ISN),之后序号值=ISN+数据在整个字节流中的偏移
(2)确认号(acknowledgement number):Ack序号,占32位,需要配合ACK标志位,只有ACK标志为1时,确认序号字段才有效,整个字段为收到的序号值+1
(3)标志位(Flags):共6个,即URG、ACK、PSH、RST、SYN、FIN等。具体含义如下:
URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。
PSH:接收方应该尽快将这个报文交给应用层。
RST:重置连接。
SYN:发起一个新连接。
FIN:释放一个连接。
TCP通讯主要是靠上图中的6个标志位
下图是一次TCP通讯的时序图


三次握手是由内核完成的,这个过程在用户看来体现在服务端accept()执行完成,在客户端体现在connect()函数完成。
比如客户端发起了SYN=1创建连接的请求(第一次握手),如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包,这时候客户端由于没有建立连接就会重新发出创建连接的请求,服务器就会重新开启一个端口连接。那么服务器端上没有接收到请求数据的上一个端口就一直开着,长此以往,这样的端口多了,就会造成服务器端开销的严重浪费。
还有一种情况是已经失效的客户端发出的请求信息,由于延时或者其他原因传输到了服务器端,服务器端以为是正常客户端发出的有效请求,接收后就会产生错误。
所以我们需要“第三次握手”来确认这个过程,让客户端和服务器端能够及时地察觉到因为网络等一些问题导致的连接创建失败,这样服务器端的端口就可以关闭了不用一直等待。

服务端不用每次都应答,只应答最后一条就可以
为什么四次,是因为半关闭
连接建立以后是全双工的,客户端给服务端说要关闭,服务端给客户端说同意关闭,这只是完成了客户端不能再给服务端发送数据了,但是服务端还是能给客户端发数据,这里关闭的是socket里的发送缓冲区,但是接收缓冲区还开着
在服务端想要关闭给客户端说了以后,这里虽然客户端已经关闭了发送缓冲区,但是还能自由的发送数据,因此还能给服务端发数据
