tcp三次握手端口号(tcp通信三次握手)
简述TCP协议的三次握手过程,以及序列号和确认号的作用
(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
TCP会话的每一端都包含一个32位(bit)的序列号,该序列号被用来跟踪该端发送的数据量。每一个包中都包含序列号,在接收端则通过确认号用来通知发送端数据成功接收
TCP 建立连接前的三次握手
所谓的“三次握手”:为了对每次发送的数据量进行跟踪与 协商 ,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时 撤消 联系,并建立虚连接。
为了提供可靠的传送, TCP 在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包 传送 给目标机之后的确认消息。TCP总是用来发送大批量的数据。当 应用程序 在收到 数据 后要做出确认时也要用到TCP。
第一次握手:建立连接时, 客户端 发送 syn 包(seq=j)到 服务器 ,并进入 SYN_SENT 状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手: 服务器 收到 syn 包,必须确认客户端的SYN( ack =j+1),同时自己也发送一个SYN包(seq=k),即SYN+ACK包,此时服务器进入 SYN_RECV 状态。
第三次握手: 客户端 收到 服务 器的SYN+ACK包,向 服务器 发送确认包ACK( ack =k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED (TCP连接成功)状态,完成三次握手。
在 三次握手协议 中, 服务器 维护一个未连接队列,该队列为每个 客户端 的SYN包( seq =j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在 服务器 处于 Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
表示内核为相应套接字排队的最大连接个数。SYN-ACK重传次数 服务器 发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。
是指半连接队列的条目存活的最长时间,也即 服务 器从收到SYN包到确认这个 报文 无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。
TCP三次握手(gold_axe)
应用程序(浏览器)调用 Socket 库的 connect :
connect( 描述符 , 服务器 IP 地址和端口号 , … )
浏览器提供了服务器的 IP 地址和端口号(这能唯一标识一个进程,这模式叫Socket),这些信息会传递给 协议栈 (操作系统的网络控制软件叫作协议栈)中的 TCP 模块。
然后就开始 三次握手 :TCP为了提供可靠的传送,客户端和服务端先发送无内容只有头部的包,来确认能力没问题, 这样就证明连接是通的, 可以正式发数据了. 并且核对了Seq值
主要是为了防止 服务器开销的浪费
2次握手以后, 两个应用程序之间建立了一个全双工 (full-duplex) 的通信。
这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。
如果没有第三次,就是请求方的返回, 不确认 请求方真的可以收到数据 (可能延时导致客户端放弃收这次响应了),
不知道对客户端来说连接已经创建失败了,服务端就一直傻等客户端的永远不会发生(客户端认为已经失败,重新开始握手)的正式发生请求,太浪费了, 会被攻击
包含很多字段,重点是发送方和接收方的端口号,和控制位
客户端(发送方)的套接字准确找到了服务器(接收方)的套接字,也就是搞清楚了我应该连接哪个套接字。
将 头部中的控制位的 SYN 比特(TCP头控制位的其中一位)设置为 1 ,表示连接开始.
TCP 头部创建好之后,接下来 TCP 模块会将信息传递给 IP 模块并委托它进行发送。IP 模块执行网络包发送操作后,网络包就会通过网络到达服务器,然后服务器上的 IP 模块会将接收到的数据传递给 TCP 模块,
服务器的 TCP 模块根据 TCP 头部中的信息找到端口号对应的套接字,也就是说,从处于等待连接状态的套接字中找到与 TCP 头部中记录的端口号相同的套接字就可以了。当找到对应的套接字之后,套接字中会写入相应的信息,并将状态改为正在连接.
上述操作完成后,服务器的 TCP 模块会返回响应,这个过程和客户端一样,在 TCP 头部中设置发送方和接收方端口号以及
SYN 比特,设置为1,表示Seq已设置,
ACK 比特((TCP头控制位的其中另一一位)设为1 ,表示ACK确认号(告知对方收到数据的第几个字节的,这次是发生方的Seq+1)有效,已经收到对方之前发的数据了,
将 TCP头部传递给 IP 模块,并委托 IP 模块向客户端返回响应。
然后,网络包就会返回到客户端,通过 IP 模块到达 TCP 模块,
通过 TCP 头部的信息确认连接服务器的操作是否成功。如果 SYN 为 1 则表示连接成功,这时会向套接字中写入服务器的 IP 地址、端口号等信息,同时还会将状态改为连接完毕。
最后一个步骤,客户端也需要 将 ACK 比特设置为 1 ,表示ACK号生效(值为服务端发来的Seq+q),并发回服务器,告诉服务器刚才的响应包已经收到。
当这个服务器收到这个返回包之后,连接操作才算全部完成。现在,套接字就已经进入随时可以收发数据的状态了,大家可以认为这时有一根管子把两个套接字连接了起来。当然,实际上并不存在这么一根管子,不过这样想比较容易理解,网络业界也习惯这样来描述。这根管子,我们称之为 连接 。只要数据传输过程在持续,也就是在调用 close 断
开之前,连接一直存在。
建立连接之后,协议栈的连接操作就结束了,也就是说 connect 已经
执行完毕,控制流程被交回到应用程序。
SYN flood洪水攻击 防范 待看
保活机制:
5.2、tcp三次握手详析,telnet,wireshark示范
发送数据包后服务端会给个收到确认包,再另外发数据返回包。
1、TCP连接的三次握手(服务器也可以主动关闭连接)
1.1、最大传输单元MTU(maximum transfer unit)
每个数据包包含的数据最可以有多少个字节,大约是1.5K
比如要发送100k的数据,操作系统会把这100k分成若干个包【分片】。
各自传送的路径可能不同,每个包可能被路由器或者交换机再次分片。
对端再次重组。
1.2、TCP包头结构
源端口,目标端口
关注SYN位,和ACK位
一个tcp包是可能没有包体,通过设置标志位达到传输控制信息的作用。
1.3、数据包首发之前的准备工作
建立tcp连接,
1.4、TCP三次握手建立连接的过程
1、客户端给服务器发送了一个SYN标志位置为1的无包体的数据包。
可能带一个序列号x,或者最大接收窗口。
2、服务器收到了SYN标志位被置位的数据包,
服务器回SYN和ACK位同时置位的数据包,序列号y,确认号x+1。
3、客户端再次发送ACK位被置位的无包体数据包,序列号x+1,确认号y+1。
1.5、为什么TCP握手是三次而不是两次。
确保数据稳定可靠的收发。减少伪造数据包对服务器的攻击。
第一次可能是伪造的请求连接,
需要拨回去应答ack包,此时伪造端收不到。
使源端下一次发送序列号+1。
拒绝服务估计就是利用tcp三次握手漏洞。
大量的syn包,服务器需要返回大量的ack,消耗服务器资源。
2、telnet工具使用介绍
是一款命令行方式运行的tcp客户端通讯工具。可以发送和接收数据。
命令格式:telnet ip port
3、wireshark监控进出本地服务器数据包
软件,分析网络数据包,windows平台上的,先要安装抓包工具
抓包:视图-重置布局
3.1、TCP断开的四次挥手
动画图解TCP三次握手
TCP 三次握手过程不管是对于本科计算机网络学习还是考研考计网的同学来说都是必考的一个,所以要掌握 TCP 整个握手的过程显得尤为重要。
一、TCP 是什么?
TCP是Transmission Control Protocol(传输控制协议) 的简称,它提供一种面向连接的、可靠的、基于字节流的传输层通信协议。
在学习 TCP 握手过程之前,我们首先要了解 TCP 报文头部的一些标志信息,因为在 TCP 握手的过程中,要用到TCP报文头部的一些信息。
TCP头部
1.1 源端口和目的端口
对于端口,我们可以这么理解:我们可以想象发送方很多的窗户,接收方也有很多的窗户,这些窗口都标有不同的端口号,源端口号和目的端口号就分别代表从哪个规定的串口发送到对方接收的窗口。不同的应用程序都有着不同的端口,比如HTTP端口80,SMTP端口25等。
1.2 序号
TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。接收端根据这个编号进行确认,保证分割的数据段在原始数据包的位置。
通俗一点的讲,每个字段在传送中用序列号来标记自己位置的,而这个字段就是用来完成双方传输中确保字段原始位置是按照传输顺序的。(发送方是数据是怎样一个顺序,到了接受方也要确保是这个顺序)
1.3 确认号
确认号是期望收到对方下一个报文段的第一个字节的序号。确认号 = N,则表示到序号N-1为止的所有数据都已经正确收到。例如:B正确收到了A发送过来的一个报文段,其序号字段值为500,而数据字段长度是200字节(序号501~700),这表明B正确收到了A发送的到序号700为止的数据,因此B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。
1.4 标志位
TCP首部中有 6 个标志比特,它们中的多个可同时被设置为?1,主要是用于操控?TCP?的状态机的,依次为URG,ACK,PSH,RST,SYN,FIN。今天我们只介绍我们用到的三个。
1.4.1 确认ACK
这个标志位可以理解为发送端发送数据到接收端,发送的时候 ACK置 为 0,一旦接收端接收数据之后,就将 ACK 置为 1,发送端接收到之后,就知道了接收端已经接收了数据。需要注意的一点是:当且仅当ACK = 1时,确认号字段才有效。TCP规定,在连接建立后,所有传送的报文段 都将ACK置为1。
1.4.2 同步SYN
SYN是同步序列号,在建立TCP连接时用来同步序号。当SYN=1,ACK=0时,表明这是一个连接请求报文段。若对方同意建立连接,则应在响应的报文段中使SYN=1,ACK=1。因此,SYN置为1就表示这是一个连接请求或连接接受报文。
1.4.3 终止FIN
当发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送方FIN标志位置为1后,表示此报文段的发送方数据发送完毕,请求释放连接。
二 T CP三次握手过程
TCP 三次握手的过程解决以下三个问题
1.要是每一方都能确知对方的存在
2.要允许双方协商一些参数(如窗口最大值,是否使用窗口扩大选项以及时间戳选项等)
3.能够对运输实体资源(如缓冲大小、连接表中的项目等)进行分配
掌握了这些,TCP 的三次握手就简单多了。下面我们就以动画形式进行拆解三次握手过程。
初始状态 :客户端处于closed(关闭)状态,服务器处于listen(监听)状态
第一次握手 :客户端发送请求报文将SYN = 1同步序列号和初始化序列号seq = x发送给服务端,发送完之后客户端处于SYN_Send状态。
第二次握手 :服务端受到SYN请求报文之后,如果同意连接,会以自己的同步序列号SYN(服务端) = 1、初始化序列号seq = y和确认序列号(期望下次收到的数据包)ack = x+ 1以及确认号ACK = 1报文作为应答,服务器为SYN_Receive状态。
第三次握手 : 客户端接收到服务端的SYN + ACK之后,知道可以下次可以发送了下一序列的数据包了,然后发送同步序列号ack = y + 1和数据包的序列号seq = x + 1以及确认号ACK = 1确认包作为应答,客户端转为established状态。
三、为什么不能是一次、二次握手,而必须是三次握手?
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
所谓“已失效的连接请求报文段”是这样产生的。考虑一种正常情况:A发出连接请求,但因连接请求报文丢失而未收到确认。于是A在重传一次连接请求,后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。在此过程中,A一共发送了两个连接请求报文段,其中一个丢失,第二个到达了B。没有已经失效的报文段。
但现在出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以至延误到连接释放以后的某个时间才到达B。本来这是一个早已经失效的报文段,但B收到此失效的连接请求报文段后,就误认为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。
由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据,但B却以为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样白白浪费了。
采用三次握手的办法可以防止上述现象的发生,例如在刚才的情况下,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要求建立连接。
TCP 连接详解
1、先提出一个问题, 可以不进行三次握手直接往服务端发送数据包吗?
是不可以的,也是可以的 ;
1)不可以是因为现在的TCP连接标准和规范要求传输数据前先确认两端的状态,有一端状态不OK的话,发数据包有什么用呢;
2)说可以是站在网络连接的角度,像 UDP 协议;
2、TCP三次握手
1)标志位、随机序列号和确认序列号是在数据包的 TCP 首部里面;
2)几个状态是指客户端和服务端连接过程中 socket 状态;
3)第一次握手,客户端向服务端发送数据包,该数据包中 SYN 标志位为 1,还有随机生成的序列号c_seq,客户端状态改为 SYN-SENT ;
4)第二次握手,服务端接收到客户端发过来的数据包中 SYN 标志位为 1,就知道客户端想和自己建立连接,服务端会根据自身的情况决定是拒绝连接,或确定连接,还是丢弃该数据包;
拒绝连接,会往客户端发一个数据包,该数据包中 RST 标志位为 1,客户端会报 Connection refused ;
丢弃客户端的数据包,超过一定时间后客户端会报 Connection timeout;
确定连接时会往客户端发一个数据包,该数据包中 ACK 标志位为 1,确认序列号 ack=c_seq+1,SYN 标志位为 1,随机序列号 s_seq,状态由 LISTEN 改为 SYN-RCVD ;
5)第三次握手,客户端接收到数据包会做校验,校验ACK标志位和确认序列号 ack=c_seq+1,如果确定是服务端的确认数据包,改自己的状态为 ESTABLISHED ,并给服务端发确认数据包;
6)服务端接到客户端数据包,会校验ACK标志位和确认序列号 ack=s_seq+1,改自己的状态为 ESTABLISHED ,之后就可以进行数据传输了;
7)建立连接时的数据包是没有实际内容的,没有应用层的数据;
8)建立连接之后发起的请求数据包,每个数据包都会封装各层协议的头部信息,标志位ACK为1,其他标志位变动;
9)网络进程间的通信,一台服务器内部的进程间通信不用这样;
3、TCP 连接三次握手抓包
1)Socket 在 linux 系统中是一种特殊的文件,因为 linux 系统的理念就是【一切皆文件】,是系统内核级的功能;
2)以上定义比较具体,可以抽象来理解,是一个内核级的用于通信的功能层,包含一组接口函数,这些函数实际就是操作 socket 文件句柄文件描述符;
一个 TCP 连接由四要素【源IP、源Port、目标IP、目标Port】唯一标识,也即 socket 由这四要素唯一确定;
一个 TCP 连接的建立也就是客户端、服务端创建了相对应的一对 socket,客户端和服务端之间的通信也就是这对 socket 间的通信(物理层面是网卡在发送/接收比特流数据);
3) 一个服务与另一个服务建立连接,他们的端口是什么呢 ?
客户端发出请求端口号是随机的,服务端是进程监听的端口号;
2、socket 主要函数介绍
1、进程通信,一个进程只有一个监听 socket,connect socket 是针对一个客户的一个连接的,有很多个; 2、connect 函数内部在发起请求前会找系统随机一个端口号; 3、连接建立后,客户端发起请求传输数据,服务端会直接交给 connect socket 处理,不会交给监听 socket 处理;
4、监听 socket 在处理客户端请求时,如果此时其他客户端发请求过来,监听 socket 是没法处理的,此时系统会维护请求队列由 backlog 参数指定;
全连接队列(completed connection queue)
半连接队列(incomplete connection queue)
Linux 内核 2.2 版本之前 ,backlog 的大小等于全连接队列和半连接队列之和;
Linux 内核 2.2 版本之后 ,backlog 的大小之和全连接队列有关系:
半连接队列大小由 /proc/sys/net/ipv4/tcp_max_syn_backlog 文件指定,可以开很大;
全连接队列大小由 /proc/sys/net/core/somaxconn 文件和 backlog 参数指定,取两个中的最小值;
tomcat acceptCount 就是配置全连接队列大小;
3、socket 函数在建立连接和数据传输的大概使用情况
4、TCP首部结构
1)2的16次方等于 65536,所以系统中端口号的限制个数为 65536,一般1024以下端口被系统占用;
2)标志位这里是 6 个,还有其他标志位的,只是这 6 个标志位常用;
3)seq 序列号,ack 确认序列号,序列号在数据传输时分包用到。三次握手时 seq 序列号是随机的,没有实际意义;
4)TCP 包首部后面接着的是 IP 包首部,再紧接着的是以太网包首部,其实都是加 0101010101 二进制位;
几个常用标志位,首先一个标志位占一个 bit 位,只能是二进制中的 1 或 0;
1)SYN ,简写 S ,请求标志位,用来建立连接。在TCP三次握手中收到带有该标志位的数据包,表示对方想与己方建立连接;
2)ACK ,简写【.】 ,请求确认/应答标志位,用于对对方的请求进行应答,对方收到含该标志位的数据包,会知道己方存在且可用。也会用在连接建立之后,己方发送响应数据给对方的数据包中;
3)FIN ,简写 F ,请求断开标志位,用于断开连接。对方收到己方的含该标志位的数据包,就知道己方想与它断开连接,不再保持连接;
4)RST ,简写 R ,请求复位标志位,因网络或己方服务原因导致有数据包丢失,己方接收到的数据包序列号与上一个数据包的序列号不衔接,那己方会发送含该标志位的数据包告诉对方,对方接收到含该标志位的数据包就知道己方要求它重新三次握手建立连接并重新发送丢失的数据包,一般断点续传会用到该标志位;
还有就是如果对方发过来的数据错了,有问题,己方也会发送含该标志位的数据包;
5)PSH ,简写 P ,推送标志位,表示收到数据包后要立即交给应用程序去处理,不应该放在缓存中,read()/write() 都有缓存区;
6)URG ,简写 U ,紧急标志位,该标志位表示 tcp 包首部中的紧急指针域有效,督促中间层尽快处理;
7)ECE,在保留位中;
8)CWR,在保留位中;
5、TCP 抓包
1)服务端会根据自身情况,没有要处理的数据时会把第二次和第三次挥手合并成一次挥手,此时标志位 FIN=1 / ACK=1;
2)MSL 是 Maximum Segment Lifetime 缩写,指数据包在网络中最大生存时间,RFC 建议是 2分钟;
详细描述:
1)客户端、服务端都可以主动发起断开连接;
2)第一次挥手,客户端向服务端发送含 FIN=1 标志位的数据包,随机序列号 seq=m,此时客户端状态由 ESTABLISHED 变为 FIN_WAIT_1 ;
3)第二次挥手,服务端收到含 FIN=1 标志位的数据包,就知道客户端要断开连接,服务端会向客户端发送含 ACK=1 标志位的应答数据包,确认序列号 ack=m+1,此时服务端状态由 ESTABLISHED 变为 CLOSE_WAIT ;
4)客户端收到含 ACK=1 标志位的应答数据包,知道服务端的可以断开的意思,此时客户端状态由 FIN_WAIT_1 变为 FIN_WAIT_2 ;(第一、二次挥手也只是双方交换一下意见而已)
5)第三次挥手,服务端处理完剩下的数据后再次向客户端发送含 FIN=1 标志位的数据包,随机序列号 seq=n,告诉客户端现在可以真正的断开连接了,此时服务端状态由 CLOSE_WAIT 变为 LAST_ACK ;
6)第四次挥手,客户端收到服务端再次发送的含 FIN=1 标志位的数据包,就知道服务端处理好了可以断开连接了,但是客户端为了慎重起见,不会立马关闭连接,而是改状态,且向服务端发送含 ACK=1 标志位的应答数据包,确认序列号 ack=n+1,此时客户端状态由 FIN_WAIT_2 变为 TIME_WAIT ;
等待 2 个MSL 时间还是未收到服务端发过来的数据,则表明服务端已经关闭连接了,客户端也会关闭连接释放资源,此时客户端状态由 TIME_WAIT 变为 CLOSED ;
也就是说 TIME_WAIT 状态存在时长在 1~4分钟;
7)服务端收到含 ACK=1 标志位的应答数据包,知道客户端确认可以断开了,就立即关闭连接释放资源,此时服务端状态由 LAST_ACK 变为 CLOSED ;
SYN 洪水攻击(SYN Flood)
是一种 DoS攻击(拒绝服务攻击),大概原理是伪造大量的TCP请求,服务端收到大量的第一次握手的数据包,且都会发第二次握手数据包去回应,但是因为 IP 是伪造的,一直都不会有第三次握手数据包,导致服务端存在大量的半连接,即 SYN_RCVD 状态的连接,导致半连接队列被塞满,且服务端默认会发 5 个第二次握手数据包,耗费大量 CPU 和内存资源,使得正常的连接请求进不来;