TCP协议简单总结

经典协议状态机变化

协议状态机
正常连接:
客户端: 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内核对连接的处理过程
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的链接请求就不能处理了。

协议头以及服务器应用
tcp协议头
服务端中状态机的唯一表示:
1. 发送方IP+发送方端口+应用层的序列号(异步事务必须支持)
2. 发送IP+发送方端口+接收IP+接收端口+应用层的序列号(异步事务必须支持)

参考文档

参考资料1:

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小她爹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值