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
相关文章推荐
- android6.0Okhttp网络请求
- http协议详解
- Linux网络编程--select,poll和epoll的区别
- Android Studio找不到org.apache.http中的类
- (转)对Http协议的长连接和短连接新的认识
- socket通讯原理以及tcp、ip三次握手机制分析
- HTTP in iOS你看我就够
- xdoe7 Transport security has blocked a cleartext HTTP
- Tomcat7启动报错:Exception in thread "http-apr-8080-exec-6" java.lang.OutOfMemoryError: PermGen space
- 神经网络入门--学习资源
- HTTP的长短连接、长短轮询的区别(转载)
- UDP和TCP区别
- 卷积神经网络源码——最终输出部分的理解
- Android中okhttp的基本用法2(okHttp的简单封装)
- 关于HTTP GET请求的url中文参数编码
- Android中关于Volley的使用(九)认识HurlStack(HttpClientStack)
- AJAX——XMLHttpRequest
- 计算机网络之TCP/IP协议(网络通讯协议)
- 对于网络不稳定,生成重复工单的解决办法
- 网络爬虫:异常处理