TCP的三次握手:
1.服务器必须准备好接受外来的连接.这通常通过调用socket bind和listen这三个函数完成,我们称为被动打开.
2.客户通过调用connect发起主动打开.这导致客户TCP发送一个SYN分节,它告诉服务器客户将在连接中发送的数据的初始序列号.通常SYN分节不携带数据,其所在IP数据报只含一个IP首部,一个TCP首部及可能有的TCP选项.
3.服务器必须确认客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将再同一连接中发送的数据的初始序列号.服务器在单个分节中发送SYN和对客户SYN的ACK.
4.客户必须确认服务器的SYN.
四次挥手:
1.某个应用进程首先调用close,我们称该端执行主动关闭.该端的TCP于是发送一个FIN分节,表示数据发送完毕.
2.接受到这个FIN的对端执行被动关闭.这个FIN由TCP确认.它的接收也作为一个文件结束符传递给接收端应用进程,因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收.
3.一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字.这导致它的TCP也发送一个FIN.
4.接收这个最终FIN的原发送端TCP确认这个FIN.
其中步骤2和3有可能合并成一个分节.
TCP状态转换图和时序图:https://blog.csdn.net/yusiguyuan/article/details/39666565.
参考这个,博主不会画也懒得画.
其中里面有个TIME_WAIT状态.TIME_WAIT状态发生在主动关闭的一方,TIME_WAIT状态持续的时间是2MSL(最大分节生命周期).
TIME_WAIT状态有两个存在的理由:
1.可靠地实现TCP全双工连接的终止.
2.允许老的重复分节在网络中消逝.
第一个理由假设最后的ACK丢失了,那么维持这个状态就可以重新发送ACK.
第二个理由是如果关闭连接后,过一段时间同样的连接再次建立,后一个连接称为前一个的化身,TCP必须防止某个连接的老的重复分组在该连接已终止后再现,从而被误解成同一连接的某个新的化身,为了做到这点,再TIME_WAIT期间TCP将不给这种状态的连接发起新的化身.保证每次成功连接TCP,来自该连接先前的化身的老的重复分组都在网络中消逝了.
可以通过socket选项设置,来避免TIME_WAIT状态。
流量控制和拥塞控制:https://blog.csdn.net/seu_calvin/article/details/53198282
这篇讲的挺不错,可以看下,不过博主作为原ACMER,老对滑动窗口这个概念想起two pointer,不过确实也差不多.
TCP/IP报头:https://blog.csdn.net/ythunder/article/details/65664309
这个讲得比较简介易懂,emmmm起码我想要的有了.
TCP两次握手可能会导致重复连接,如果A第一次发送SYN阻塞了,那么就会重传,然后B收到后建立连接,后来一开始的包发送过来了那么B会以为这是第二次连接同样发一个ACK回去,然后等待数据传送。
TCP三次握手可能会造成SYN flood。
TCP和UDP的区别:
1. UDP没有拥塞控制和流量控制,不提供确认、序列号、RTT估算、超时重传等级制。
2. UDP是无连接,不可靠,消耗资源较少,TCP是面向连接的,可靠,消耗资源较多。
3. UDP的不需要维护关于连接状态的信息
4. UDP的报文段首部是8个字节,TCP是20个字节
5. TCP是字节流模式,UDP是数据报模式.
TCP选项:
window scale选项:用于增加窗口大小,在如今网速比较快的时代16位的窗口大小已经不够用了。
SACK选项:允许确认非连续片段的ACK,用于告知真正丢的包,只重传丢失片段。
timestamp选项:解决计算RTT时间的问题,为PAWS提供消息依据。
tw_recycle选项:快速回收TIME_WAIT状态的连接,必须和上面的选项配合使用。
socket选项:
tcp_maxseg选项:设置最大分节MSS。
tcp_nodelay选项:开启本选项则禁用Nagle算法。
Nagle算法:任意时刻只能由一个未被确认的小段(小于MSS则为小段)。
延迟ACK:顾名思义,接受到数据后不立刻发送ACK,等待一小段时间再发送,TCP期待在这段时间内自身有信息发送回对端。被延迟的ACK就可以由这些数据捎带,从而省掉一个分节。
TCP有四种不同的计时器:
重传计时器:就是超时重传用的计时器。
坚持计时器:零窗口探测报文发出后需要启动一个计时器去检查什么时候能发数据。
保活计时器:就是用于keep-alive发送心跳包的。
2MSL计时器:这个更明显,就是用于TIME_WAIT的。