复习三次握手以及相关问题_一个博客id_新浪博客

复习三次握手以及相关问题


三次握手开始是由客户端connect()开启的

在三次握手中,服务器端会经过俩个状态,SYN_RECV和ESTABLISHED才可以进行

我们知道,服务器端会维护俩个队列半连接队列和全连接队列

半连接队列:当一个连接变为SYN_RECV状态是处于半连接队列;
全连接队列:当连接从SYN_RECV  ->  ESTABLISHED  会从半连接队列转移到全连接状态,应用程序只需要从全链接队列中获取需要处理的请求即可。

listen(sockfd,backlog)函数会做俩件事情:
1.将套接字转成listen状态,被动的等待客户端来连接;
2.设置每个套接字的最大连接队列。    内核中是一个宏定义:默认大小为128

参数的意义:
sockfd被监听的套接字
backlog早期的版本指的是未完成三次握手和已完成三次握手的队列的总长度,后面的linux的版本指的是未完成三次握手的对列 长度。

如果监听队列满了,服务器将不再受理新的连接。

几个三次握手过程中的问题:
1.当客户端给服务器端发送ACK后,客户端进入了ESTABLISHED状态,但是实际上服务器没有收到客户端的ACK,此时客户端使用write向服务器发送消息会发生什么状况?

答:客户端发送的数据包并不能到达网络:原因比较复杂,
当数据报经过客户端的层层封装,到达服务器端,服务器并不认识,因为服务器从来没有给改连接的客户端分配过clifd,所有服务器端不知道该怎么处理这个包,干脆直接给丢弃掉。
而客户端调用write将数据仅仅是写到了发送缓存区,write返回成功,可怕的是客户端并不知道自己和服务器端还没有真正的建立连接。这种极限的情况下,由于客户端一直收不到服务器端的ACK,客户端会重复的发送自己的数据报。
而服务器不会允许这样重重复复的这样进行,最终服务器端会发送一个复位报文给客户端。


2.服务器什么时候会进行丢ACK包,重传ACK_SYN包?

答:当客户端的ACK到达服务器端,首先服务器的TCP内核先要检查一下这个ACK包的正确性,检查无误后,
再检查一下服务器这边的全连接队列满了没,如果满了,服务器会直接丢弃这个报文。然后服务器主动重新向客户端发送ACK+SYN报文,表示刚才我这边比较忙咱们重新建立链接吧,等该报文到达客户端后,客户端会重新给服务器端发送ACK.(这个过程相当于服务器成了主动方,客户端成了被动连接方,但是这个过程也是有限的,最多持续五次,如果还连接不上,服务器:我也不管了!!!)。


3.为什么不是俩次握手,为什么不是四次呢?

答:俩次?这里假设是俩次握手
假设一个情景第一次客户端给服务器端发送SYN,但是由于网络问题,这个包延迟了,客户端大哥耐不住性子,重新发送SYN希望建立连接,这次服务器端收到了SYN,给客户端回馈SYN+ACK,连接成功建立了。
但是之前由于网络阻塞迟到的报文到了,服务器也回了个SYN_ACK,客户端收到这个报文一脸懵逼,发的啥玩意儿,干脆扔了,然后客户端就和服务器端用第一次建立的线路通信着,第二次的链路虽然连接好了,但是没用到,浪费了资源。

为什么不是四次?
可以,将SYN_ACK报文拆分为俩次发送,就达成了四次,可是一次能做完的事干嘛要分俩次做。

那照你这样说,四次挥手为什么不合并成三次,服务器端回馈ACK和主动发送FIN合并成一次。

FIN代表没有数据要发送了,如果合并成一次,服务器端还要话说,会不会把服务器憋着了。。。


4.保活计时器是干什么的?

当TCP建立连接后,如果超过俩个小时没有收到客户端的消息,服务器会每隔 75分钟发送一个探测报文,如果接连发送10个都没有回应,就认为客户端出了故障,关闭掉连接。


5.什么是SYN攻击,发生在什么时候,该怎么防御呢?

答:
SYN攻击原理:
服务器接收到连接请求,将此信息加入未连接队列,并发送请求包给客户,此时进入SYN_RECV状态。 当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪



怎么判断是不是一次SYN攻击呢?
我们知道通过netstat -natp查看到如果有大量的SYN_RECV状态(导致的是未连接队列爆满不够用),并且这些IP都是一些大量的随机值,基本上可以判定这是一次SYN的攻击


该怎么缓解这个问题呢?

1.增大未完成三次握手监听队列的大小,可以适当的缓解,但是增大的时候还是要考虑内核资源的分配均匀的问题,不能一味的增加;
2.增加中间层:不用真正的服务器直接去处理这些SYN包,而是代理服务器去处理,减轻服务器的压力

3.SYN cookies技术
在TCP实现中,当收到客户端的SYN请求时,服务器需要回复SYN+ACK包给客户端,客户端也要发送确认包给服务器。通常,服务器的初始序列号由服务器按照一定的规律计算得到或采用随机数(ISN),但在SYN cookies中,服务器的初始序列号是通过对客户端IP地址、客户端端囗、服务器IP地址和服务器端囗以及其他一些安全数值等要素进行hash运算,加密得到的,称之为cookie。当服务器遭受SYN攻击使得backlog队列满时,服务器并不拒绝新的SYN请求,而是回复cookie(回复包的SYN序列号)给客户端, 如果收到客户端的ACK包,服务器将客户端的ACK序列号减去1得到cookie比较值,并将上述要素进行一次hash运算,看看是否等于此cookie。如果相等,直接完成三次握手(注意:此时并不用查看此连接是否属于backlog队列)。



6.linux下TCP连接异常关闭的现象汇总:

a. 默认情况下(不改变socket选项),当你调用close时,如果发送缓冲中还有数据,TCP会继续把数据发送完

b. 发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。

c. 应用层如何知道对端关闭?通常,在最简单的阻塞模型中,当你调用recv时,如果返回0,则表示对端关闭。在这个时候通常的做法就是也调用close,那么TCP层就发送FIN,继续完成四次握手。如果你不调用close,那么对端就会处于FIN_WAIT_2状态,而本端则会处于CLOSE_WAIT状态。这个可以写代码试试。

d. 在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关闭,你可以写代码试试。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值