您的位置:首页 > 理论基础 > 计算机网络

TCP协议简单总结

2016-04-14 15:03 585 查看

经典协议状态机变化



正常连接:

客户端: 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卷一详解修订下

关闭时序图另外一种表示方式



常见问题

服务器保持了大量TIME_WAIT状态

一般情况下,作为客户端请求第三方服务,没有进行主动关闭。

服务器保持大量CLOSE_WAIT状态

服务器接收客户端的关闭操作,没有进行关闭。

一、解决:

原因是因为调用ServerSocket类的accept()方法和Socket输入流的read()方法时会引起线程阻塞,所以应该用setSoTimeout()方法设置超时(缺省的设置是0,即超时永远不会发生);超时的判断是累计式的,一次设置后,每次调用引起的阻塞时间都从该值中扣除,直至另一次超时设置或有超时异常抛出。

比如,某种服务需要三次调用read(),超时设置为1分钟,那么如果某次服务三次read()调用的总时间超过1分钟就会有异常抛出,如果要在同一个Socket上反复进行这种服务,就要在每次服务之前设置一次超时。

二、规避:

调整系统参数,包括句柄相关参数和TCP/IP的参数;

具体措施见:参考资料1

TCP协议头

linux内核对连接的处理过程



  内核会为处于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的链接请求就不能处理了。

协议头以及服务器应用



服务端中状态机的唯一表示:

1. 发送方IP+发送方端口+应用层的序列号(异步事务必须支持)

2. 发送IP+发送方端口+接收IP+接收端口+应用层的序列号(异步事务必须支持)

参考文档

参考资料1:

http://blog.csdn.net/wesleyluo/article/details/6079139

参考资料2:

http://blog.chinaunix.net/uid-16979052-id-3350958.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: