TCP 三次握手和四次挥手指的什么?
为什么要三次握手 三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常所以三次握手就能确认双发收发功能都正常,缺一不可。 第四次握手:任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
只知道三次握手,A向B发送信息,B会向A返回一个收到确认的消息,A还会对这个确认消息发送一次再确认,所以一个消息要经过三次的消息交互才算发送完成,这就是三次握手

TCP协议的三次握手过程的缺陷,易受到什么攻击
tcp协议是一种面向连接的可靠协议,它规定在正式传输数据之前必须建立起连接关系,过程是a向b发送syn包,b收到后发送ack+syn包,a收到后向b发送ack包。这个过程称为三次握手,经过三次握手后发送的数据才会被接收。 利用tcp协议的攻击原理是a向b发送一个syn包,b返回ack+syn包,但a不再发送ack确认包,那么b将就这样一直等待a返回的确认包,占用了连接资源,这样的状况成为半开连接,直到连接超时才会关闭连接。如果a向b发送大量的syn包,b的网络连接资源将被耗尽,就构成了攻击。还有更坏的一种方式是在发送的syn包中把源地址设为一个不存在的地址,服务器向一个不存在的地址发送请求包自然得不到回应。

TCP中三个函数与三次握手的关系?
TCP是属于网络分层中的传输层,因为OSI分为7层,感觉太麻烦了,所以分为四层就好了,简单。 分层以及每层的协议,TCP是属于传输层,如下两张图:TCP三次握手会涉及到状态转换所以这里贴出TCP的状态转换图如下:TCP三次握手简述TCP三次握手如图:第一次握手客户主动(active open)去connect服务器,并且发送SYN 假设序列号为J,服务器是被动打开(passive open)第二次握手服务器在收到SYN后,它会发送一个SYN以及一个ACK(应答)给客户,ACK的序列号是 J+1表示是给SYN J的应答,新发送的SYN K 序列号是K第三次握手客户在收到新SYN K, ACK J+1 后,也回应ACK K+1 以表示收到了,然后两边就可以开始数据发送数据了使用tcpdump观察如下:因为都是在本机同时运行client和server所以命令为:tcpdump -i lo port 5555, 只能监听回路lo接口,结果如下如图用红色圈起来的就是3次握手,但是为什么最后一次握手,为什么ack = 1,而不是369535922 呢,这是因为这里的第三次握手tcpdump显示的是相对的顺序号。但是为了便于观察我们需要把tcpdump的顺序号变为绝对的顺序号。命令只需要加-S(大写)便可,即:tcpdump -i lo port 5555 -S加上之后结果就正常了如下图:从tcpdump的数据,可以明显的看到三次握手的过程是:第一次握手:client syn 2322326583 —> server第二次握手:server syn 3573692787, ack 2322326583 + 1 —> client第三次握手:client ack 3573692787 + 1 -->serverTCP三次握手详细解析过程:第一次握手客户在socket() connect()后主动(active open)连接上服务器, 发送SYN ,这时客户端的状态是SYN_SENT服务器在进行socket(),bind(),listen()后等待客户的连接,收到客户端的 SYN 后,1.半连接队列(syn queue)未满服务器将该连接的状态变为SYN_RCVD, 服务器把连接信息放到半连接队列(syn queue)里面。2.半连接队列(syn queue)已满服务器不会将该连接的状态变为SYN_RCVD,且将该连接丢弃(SYN flood攻击就是利用这个原理,对于SYN foold攻击,应对方法之一是使syncookies生效,将其值置1即可,路径/proc/sys/net/ipv4/tcp_syncookies,即使是半连接队列syn queue已经满了,也可以接收正常的非恶意攻击的客户端的请求,但是这种方法只在无计可施的情况下使用,man tcp里面的解析是这样说的,但是我不知道为什么Centos6.9默认是置为1,所以这让我很疑惑)。半连接队列(syn queue)最大值 /proc/sys/net/ipv4/tcp_max_syn_backlogSYN flood攻击攻击方的客户端只发送SYN分节给服务器,然后对服务器发回来的SYN+ACK什么也不做,直接忽略掉,不发送ACK给服务器;这样就可以占据着服务器的半连接队列的资源,导致正常的客户端连接无法连接上服务器。-----[维基百科](SYN flood攻击的方式其实也分两种,第一种,攻击方的客户端一直发送SYN,对于服务器回应的SYN+ACK什么也不做,不回应ACK, 第二种,攻击方的客户端发送SYN时,将源IP改为一个虚假的IP, 然后服务器将SYN+ACK发送到虚假的IP, 这样当然永远也得不到ACK的回应。)第二次握手服务器返回SYN+ACK给到客户端,客户端收到SYN+ACK后,状态从SYN_SENT变为ESTABLISHED,也即是connect()函数的返回。第三次握手全连接队列(accept queue)的最大值 /proc/sys/net/core/somaxconn (默认128)全连接队列值 = min(backlog, somaxconn)这里的backlog是listen(int sockfd, int backlog)函数里面的那个参数backlog1.全连接队列(accept queue)未满服务器收到客户端发来的ACK, 服务端该连接的状态从SYN_RCVD变为ESTABLISHED,然后服务器将该连接从半连接队列(syn queue)里面移除,且将该连接的信息放到全连接队列(accept queue)里面。2.全连接队列(accept queue)已满服务器收到客户端发来的ACK, 不会将该连接的状态从SYN_RCVD变为ESTABLISHED。当然全连接队列(accept queue)已满时,则根据 tcp_abort_on_overflow 的值来执行相应动作/proc/sys/net/ipv4/tcp_abort_on_overflow 查看参数值2.1 tcp_abort_on_overflow = 0则服务器建立该连接的定时器,这个定时器是一个服务器的规则是从新发送syn+ack的时间间隔成倍的增加,比如从新了第二次握手,进行了5次,这五次的时间分别是 1s, 2s,4s,8s,16s,这种倍数规则叫“二进制指数退让”(binary exponential backoff)给客户端定时从新发回SYN+ACK即从新进行第二次握手,(如果客户端设定的超时时间比较短就很容易出现异常)服务器从新进行第二次握手的次数/proc/sys/net/ipv4/tcp_synack_retries2.2 tcp_abort_on_overflow = 1关于tcp_abort_on_overflow的解析如下:意思应该是,当 tcp_abort_on_overflow 等于1 时,重置连接(一般是发送RST给客户端),至于怎么重置连接是系统的事情了。不过我在查资料的过程发现,阿里中间件团队博客说并不是发送RST, —[阿里中间件团队博客]这个博客跑的实例观察到的是服务器会忽略client传过来的包,然后client重传,一定次数后client认为异常,然后断开连接。当然,我们写代码的都知道代码是第一手的注释,实践是检验真理的唯一标准,最好还是自己以自己实践为准,因为可能你的环境跟别人的不一样。)查看全连接队列(accept queue)的使用情况如上图,第二列Recv-Q是,全连接队列接收到达的连接,第三列是Send-Q全连接队列的所能容纳最大值,如果,Recv-Q 大于 Send-Q 那么大于的那部分,是要溢出的即要被丢弃overflow掉的。感想:1.本来想写TCP连接的建立和终止的,没想到要讲清楚TCP连接的建立已经很大的篇幅了,就只讲TCP连接的建立而已。2.以前看书的时候,没有解决一个问题的来的深刻或者说脉络清晰,这个就是主题阅读的好处吧。3.以前没有养成一个遇到问题深入解析,解决问题的习惯,今后慢慢养成。下面的参考1有实例,会比较详细一点,清晰一些。参考:http://jm.taobao.org/2017/05/25/525-1/https://coolshell.cn/articles/11564.htmlhttps://zh.wikipedia.org/wiki/SYN_cookiehttps://zh.wikipedia.org/wiki/SYN_floodhttps://www.cnblogs.com/menghuanbiao/p/5212131.html————————————————版权声明:本文为CSDN博主「jun2016425」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/jun2016425/article/details/81506353
这是你创建的套接字类型决定的,常用的套接字是数据流类型(TCP)和数据报文类型(UDP),创建这些类型的套接字的时候就已经带上了相应的协议栈,这些握手信息在协议栈内部就已经实现了,不需要上层应用去实现 如果你想自己去控制握手信息,需要创建原始套接字,这种类型的套接字是基于IP层的,很多抓包工具就是通过这种类型的套接字来实现的,在这一层上你就可以自己定义处理握手信息,但这样相当于你要自己来实现TCP协议栈了,这难度太高,而且一般情况下也没必要 如果只是对握手的过程感兴趣,安装一个抓包工具观察一下连接的时候C/S之间的通信数据包就可以了
TCP需要三次握手才能建立连接,那么为什么需要三次握手呢?

tcp三次握手
客户机长时间不进行第三次握手是拒绝服务攻击的一种方式(SYN Flood攻击)。在这种情况下,形成的是一种半连接状态。服务器会一直等待到计时器超时(30~120秒)后断开半连接。 SYN Flood没有太好的防范方式。

TCP三次握手原理
本文主要内容1、TCP数据包格式TCP数据包格式如下:注意到中间还有几个标志位:数据包格式当中,最重要的是理解序号和确认序号。TCP为什么是稳定可靠的,与序号与确认序号这套机制紧密相关,这也是TCP的精髓。2、TCP的三次握手众所周知,TCP协议是可靠的,而UDP协议是不可靠的。在一些场景中必须用TCP,比如说用户登录,必须给出明确答复是否登录成功等。而有些场景中,用户是否接收到数据则不那么关键,比如网络游戏当中,玩家射出一颗子弹,另外的玩家是否看到,完全取决于当前网络环境,如果网络卡顿,就会有玩家已经被射杀,但界面仍然刷新不出来的情况。这种情形适合UDP。为了保证TCP协议可靠,在建立连接之时就要得到保证。最初两端的TCP进程都处于CLOSED关闭状态,A主动打开连接,而B被动打开连接。(A、B关闭状态CLOSED——B收听状态LISTEN——A同步已发送状态SYN-SENT——B同步收到状态SYN-RCVD——A、B连接已建立状态ESTABLISHED)B服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。若有,则作出响应。3、TCP的传输和确认TCP 传输的可靠性,可以用一句话归结:每收到对方数据,就发送 ACK 进行确定,发送方发送后没有收到 ACK 就隔一段时间重发。就是 A 向 B 发送消息(下面将 TCP 的报文直接看做是消息,消息一词跟 TCP 报文混用),B 收到消息后需要向 A 发送 ACK。这个 ACK 相当于返回结果,没有返回结果,A 就重新发送消息。归纳起来,A 有 3 种消息需要确认。另外 A 也可以发送 RST 消息,代表出错了。出错消息不需要确认。RST 也可以当成返回接口,替代正常的 ACK。返回 ACK,表示消息发送并处理成功,返回 RST 表示消息处理失败。因为通过网络传输,还有第三种结果,就是不确定成功失败。这样归纳起来。就有三种返回结果。这两种具体情况,A 根本识别不了,都只能重发。4、TCP的序号和确认序号A 向 B 发送消息,假如同时发送 a、b、c、d 消息,因为通过网络,这些消息的顺序并非固定的。而 B 返回 ACK 结果,这样就有一个问题,这个结果到底对应了哪个消息?另外当 A 超时重发后,原来的消息延时一段时候,又重新到达了 B,这样 B 就收到两条相同的消息,那么 B 怎么确定这两条消息是相同的呢?为了解决这个对应问题,每一条消息都需要有一个编号,返回结果也应该有一个编号。TCP 的序号可以看成是发送消息的编号,确认序号可以看成是返回结果的编号。有了编号,重复的消息才可以忽略,返回结果(ACK)才可以跟消息对应起来。当建立连接的时候,TCP 选定一个初始序号,之后每发送一个数据包(消息),就将序号递增,保证每发送不同的数据包,数据包的序号都是不同的。TCP 是这样处理的:SYN、FIN 也需要递增序号。不然 A 向 B 重发多个 SYN 或者 FIN, B 根本判断不了 SYN 是否相同,这样就不可以忽略重复的数据包了。当 TCP 发送 ACK 时,相当于返回结果,需要带有确认序号,以便跟发送的消息对应起来。当发送包编号为 a,递增长度为 len。其中 SYN 和 FIN 可以看成是递增长度为 1。这条消息可以这样表示为:现在来回顾三次握手过程。 A 发送序列号x给 B , B 回复 A 确认号 x+ 1,同时发送序列号 y, A 接收到 B 的回复后,再回复确认号 y+1,同时发送序列号 x+1。给对方的回复一定是接收到的序号加1(或者是数据长度),这样对方才能知道我已经收到了,这样才能保证TCP是可靠的。

本文由 在线网速测试 整理编辑,转载请注明出处。