TCP协议简单总结

经典协议状态机变化

TCP协议简单总结_第1张图片
正常连接:
客户端: CLOSED–SYN_SEND—ESTABLISHED
服务器: LISTEN—SYN收到—-ESTABLISHED
正常关闭
客户端:ESTABLISHED—FIN_WAIT_1—FIN_WAIT_2—TIME_WAIT–CLOSED
服务端:ESTABLISHED–CLOSE_WAIT—-LAST_ACK—CLOSED
同时打开
SYN_SEND—–SYN收到—-ESTABLISHED
同时关闭
ESTABLISHED—FIN_WAIT_1—CLOSING—TIME_WAIT–CLOSED

典型的时序图如下

注:从其他地址摘的,好像有点问题,需要根据查看TCP/IP卷一详解修订下

关闭时序图另外一种表示方式
TCP协议简单总结_第2张图片

常见问题

服务器保持了大量TIME_WAIT状态
一般情况下,作为客户端请求第三方服务,没有进行主动关闭。

服务器保持大量CLOSE_WAIT状态
服务器接收客户端的关闭操作,没有进行关闭。
一、解决:
原因是因为调用ServerSocket类的accept()方法和Socket输入流的read()方法时会引起线程阻塞,所以应该用setSoTimeout()方法设置超时(缺省的设置是0,即超时永远不会发生);超时的判断是累计式的,一次设置后,每次调用引起的阻塞时间都从该值中扣除,直至另一次超时设置或有超时异常抛出。
比如,某种服务需要三次调用read(),超时设置为1分钟,那么如果某次服务三次read()调用的总时间超过1分钟就会有异常抛出,如果要在同一个Socket上反复进行这种服务,就要在每次服务之前设置一次超时。
二、规避:
调整系统参数,包括句柄相关参数和TCP/IP的参数;
具体措施见:参考资料1

TCP协议头

linux内核对连接的处理过程
TCP协议简单总结_第3张图片
  内核会为处于listening状态的socket维护两个队列,一个是已经完成了三次握手的队列(TCP链接处于TCP状态机中的ESTABLISHED状态),一个是还没有完成三次握手的队列(TCP链接处于TCP状态机中的SYN_RCVD状态)。
当三次握手完成后,TCP链接就建立了,将这个成员从未完成队列已到完成队列(accept()是阻塞的,若已完成队列有链接,则返回的已完成队列的首个成员)。未完成队列中的成员有75秒生存时间。listen()的第二个参数指的是这两个队列的成员总数。
若是队列已满,server对新进来的链接不予处理,client的connect()会重新尝试链接。
  有一种DOS(denial of service)攻击叫SYN flooding,它是某个clinet疯狂的发送SYN,尝试与server建立链接,那server队列满了之后,正常的lient的链接请求就不能处理了。

协议头以及服务器应用
TCP协议简单总结_第4张图片
服务端中状态机的唯一表示:
1. 发送方IP+发送方端口+应用层的序列号(异步事务必须支持)
2. 发送IP+发送方端口+接收IP+接收端口+应用层的序列号(异步事务必须支持)

参考文档

参考资料1:

http://blog.csdn.net/wesleyluo/article/details/6079139
参考资料2:
http://blog.chinaunix.net/uid-16979052-id-3350958.html

你可能感兴趣的:(时序图,TCP状态机)