TCP协议之三次握手(二)
本节主要研究三次握手出现的一些异常情况和编程相关的知识:
上一节分析了三次握手的过程,本节会回答一些三次握手的小问题,然后利用linux系统调用实践一下简单的网络的编程。
三次握手的常见问题
Q 向一个不存在但合法的公网IP任意端口发送SYN包会出现什么情况?
A 返回ICMP主机不可达。
Q 向一个存在的IP但未绑定的端口发送SYN包会出现什么情况
A 返回 TCP RST segement
Q 第一个SYN包丢失了,客户机会采取什么动作?
A 重传,重试几次后失败,连接失败
Q 为什么建立连接过程不是四次
A Server的SYN &ACK放到一个TCP segment中传给了client
Q 什么时候将会出现4次的 TCP segment交互
A 连接同时断开
Q 第二个SYN2(SYN2 + ACK1)丢失了将会出现什么情况。
A Client收不到SYN2而不发送ACK2, Server端超时重传。
Q:ACK2丢失了将会怎么样
A: 如果出现了大量ACK丢失,未完成的队列就会出现满的状态,从而不能接受SYN1,这就是dos攻击。
三次握手编程实践
参考这里:编程实践
connect 函数能为客户端主动连接服务器,建立连接通过三次握手,而这个连接的过程是由内核完成的,不是由函数完成的。connect函数默认会一直阻塞,知道三次握手成功或者超时失败菜户返回。
对于服务器是被动连接的TCP三次握手也不是由这个函数完成的,listen作用仅仅告诉内核一些信息。而且listen函数不会阻塞,它主要做的事情是将套接字和对应度列的长度告诉linux内核,然后listen函数就结束了。
当由一个客户端主动连接,linux内核就自动完成TCP的三次握手。
三次握手的连接队列
listen()函数的第二个参数(backlog)的作用, 告诉内核连接队列的长度。为了更好理解backlog参数,我们必须认识到内核任何一个给定的监听套接口维护一个队列,该队列由两部分构成,分别是完成连接队列,未完成连接队列:
- 未完成连接队列,每当服务端收到有一个SYN分节,就会将客户端放入未完成连接队列,而服务器处于 SYN_RECV 状态
- 已完成连接队列,当客户端和服务器彻底完成三次握手的过程,客户端从未完成的连接队列升级成为已完成的连接队列,并从未完成的连接队列中清空该客户端, 这些套接口处于ESTABLISHED状态
当来自客户端的SYN到达时, TCP未完成连接队列中创建一个新项,然后知道三次握手的第三个分节到达服务器或者超时为止。
如果三次握手正常完成, 该项就从未完成连接队列移到已完成的队列的队尾。
backlog参数历史上被定义为上面两个队列的大小之和。这个数值默认是128.
accept()函数的功能是从连接队列的头部去除一个已经完成的连接,如果这个队列没有已经完成的连接,accept()函数就会阻塞,知道去除队列中已经完成的用户连接为止。
如果服务器不能及时调用accept函数及时的取走已完成的连接,队列满了会怎样。队列满了以后,服务器不会再对新建立的连接syn进行应答,所以客户端的connect就会返回ETIMEDOUT,但是linux不会这样,只是会延迟收到。具体代码参看编程实践
这个连接队列究竟是怎么工作的有待研究。
最新文章
- JS组件系列——Bootstrap Table 表格行拖拽(二:多行拖拽)
- 网卡故障:弹出界面eth0: 错误:没有找到合适的设备:没有找到可用于链接System eth0 的
- 让gcc支持成员函数模板的trick
- 【推荐】HTML5 UI框架 推荐
- java中system.out.println()是什么意思
- 老男孩python学习之作业一购物小程序
- scrapy分布式爬虫scrapy_redis一篇
- nginx 重定向 说明
- Linux 小知识翻译 - 「Linux之父 Linus」
- Python基础1 介绍、基本语法
- Linux下查找指定日期的文件
- Jquery的回调函数的使用
- IntelliJ IDEA创建maven web项目(IDEA新手适用)
- Spark RDD关联操作小结
- 使用opencv3+python实现视频运动目标检测
- Python中int()函数的用法浅析
- PHP与SQL数据库交互中文乱码怎么办
- ecmall类关系图(转)
- SCARA——OpenGL入门学习一、二
- eclipse 开发hbase 环境准备