tcp连接(tcp连接三次握手)

更新时间:2023-03-01 10:53:29 阅读: 评论:0

什么是TCP连接

  TCP即传输控制协议。TCP连接是互联网连接协议集的一种。

  TCP通信最重要的特征是:

  有序和可靠。

  有序通过将文本流分段并编号实现,可靠通过ACK回复和重复发送实现。

TCP连接状态图


  参考文章:

  TCP连接过程详解

  blog.163.com/hlz_2599/blog/static/142378474201151943414397/




什么是 TCP 连接

世界上绝大部分的 HTTP 通信都是通过 TCP/IP 承载的,TCP/IP 是全球计算机和网络设备都在使用的一种常用的分组交换网络分层协议集。客户端应用程序可以打开一条 TCP/IP 连接,连接到世界上可能运行的任何一个服务器应用程序上。一旦连接建立起来,在不断网的情况下,客户端与服务器之间交换的报文就永远不会丢失、受损或者失序。

TCP 连接详解

1、先提出一个问题, 可以不进行三次握手直接往服务端发送数据包吗?

是不可以的,也是可以的

1)不可以是因为现在的TCP连接标准和规范要求传输数据前先确认两端的状态,有一端状态不OK的话,发数据包有什么用呢;

2)说可以是站在网络连接的角度,像 UDP 协议;

2、TCP三次握手

1)标志位、随机序列号和确认序列号是在数据包的 TCP 首部里面;

2)几个状态是指客户端和服务端连接过程中 socket 状态;

3)第一次握手,客户端向服务端发送数据包,该数据包中 SYN 标志位为 1,还有随机生成的序列号c_q,客户端状态改为 SYN-SENT ;

4)第二次握手,服务端接收到客户端发过来的数据包中 SYN 标志位为 1,就知道客户端想和自己建立连接,服务端会根据自身的情况决定是拒绝连接,或确定连接,还是丢弃该数据包;

拒绝连接,会往客户端发一个数据包,该数据包中 RST 标志位为 1,客户端会报 Connection refud ;

丢弃客户端的数据包,超过一定时间后客户端会报 Connection timeout;

确定连接时会往客户端发一个数据包,该数据包中 ACK 标志位为 1,确认序列号 ack=c_q+1,SYN 标志位为 1,随机序列号 s_q,状态由 LISTEN 改为 SYN-RCVD ;

5)第三次握手,客户端接收到数据包会做校验,校验ACK标志位和确认序列号 ack=c_q+1,如果确定是服务端的确认数据包,改自己的状态为 ESTABLISHED ,并给服务端发确认数据包;

6)服务端接到客户端数据包,会校验ACK标志位和确认序列号 ack=s_q+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)q 序列号,ack 确认序列号,序列号在数据传输时分包用到。三次握手时 q 序列号是随机的,没有实际意义;

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 标志位的数据包,随机序列号 q=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 标志位的数据包,随机序列号 q=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 和内存资源,使得正常的连接请求进不来;


TCP连接建立过程

在TCP/IP中,TCP协议通过三次握手来建立连接,从而提供可靠的连接服务。

第一次握手:建立连接后,客户端向服务器发送syn包(syn=j),进入SYN_SEND状态,等待服务器确认;

第二次握手:当服务器收到syn包时,必须确认客户端的syn(ack=j+1)并发送一个syn包(syn=k),即syn+ack包。此时,服务器进入SYN_RECV状态。

第三次握手:SYN+ACK包,客户端收到服务器端发来的确认包ACK(ACK=k+1),来发送这个包来发送,客户端和服务器端进入建立状态,完成三路握手。

扩展资料:

重要概念:

无关的队列:三重握手协议、服务器维护一个独立队列,为每个客户的SYN包创建一个条目(SYN=j)表明服务器已经收到了SYN包和确认发送到客户,等待客户的确认包。

这些条目标识的连接处于服务器的Syn_RECV状态,当服务器接收到客户机的确认包时,它将删除该条目,服务器将进入已建立的状态。

Backlog参数:表示要保持的未连接队列的最大数量。

当服务器发送synack包时,如果没有收到客户端确认包,服务器将进行第一次重传,等待一段时间仍然没有收到客户端确认包,然后进行第二次重传。

如果重传号超过系统指定的最大重传号,系统将从半连接队列中删除连接信息。注意每个重传的等待时间可能不相同。

半连接生存时间:指半连接队列中条目的最长生存时间,即从接收SYN包到确认无效消息的最长服务时间。这个时间值是所有重传请求包的最长等待时间的总和。有时我们也称半连接生存时间为超时时间,SYN_RECV生存时间。


“TCP连接”究竟是什么意思?

我们经常听到"建立TCP连接","服务器的连接数量有限"等,但仔细一想,连接究竟是个什么东西,是和电话一样两端连起一根线?似乎有点抽象不是么?

1.久违的分组交换网络
似乎这个概念只有在学校里学计算机网络才能接触到,但不过今天的话题其实和它离不开关系。我们知道最早的电话网络是以很容易理解的形式存在的,就是单纯的一根线加两端的设备,设备之间所沟通的所有信息都通过一根特定的电缆来回传输,如下图:

这样的连接是我们特别好理解的,搭起两边的线,就是一个连接嘛!但是,我们讨论的是计算机网络!(严肃脸),计算机网络中两个设备节点是如何通信?

计算机网络采取分组交换技术,什么意思呢?就是我有【一块数据】要发给对方小苍,那我会把这【一块数据】分成N份【单位数据】,分别发出去,而每份【单位数据】走哪条路是不一定的,但是这些【单位数据】总要全部达到小苍手里,小苍再根据【单位数据】里记录的序号拼接起来,组成完整的【一块数据】。这就是分组的意思所在。

2.协议和协议实现
上面不小心把TCP的大体实现给说了,实际上在具体的应用中,光有大体思路是不行的,还有很多细节问题,需要两个设备之间提前约定好协议,才能协同完成通信。举个例子:A向B发了10份【单位数据】,而B其实只收到9份【单位数据】,怎么办?

TCP协议大家都应该是知道的,但协议只是想法,真正起作用的是在路由节点和设备节点上的协议软件,是运行在设备上的具体执行者,它根据协议指导,对具体数据进行控制和操作。这儿就不往下展开了。

认识到协议和协议软件这一点非常重要,因为连接的限制恰恰就是受软件在设备中资源分配的影响的。

3.连接的真面目
上面说的第一种电话网络,如果两个设备搭设了一条线,那么两个电话就一定确定对方在线,因为他俩独享一条实时存在的线。但计算机网络的连接呢?

向上面的图一样(图里不深究TCP,仅仅用来说明连接大体过程),其实他们俩并不能确保对方就是在线,只是通过几番确认,认为对方一直会在。而如果确认了对方存在,那么就会为以后的对话通讯分配内存、CPU处理时间等资源,每个设备都会在本地去维持这么一个状态,来告诉自己是有一个连接的,这些设备所花的资源和维护的状态,就是连接。而整个网络是不会记录有着一条连接的,所以说连接只是记录在各个设备的一个状态信息。

那么,到现在我们知道了,连接其实并不是所谓的有一根电线连起两个设备,而是两方确认了一下对方的存在后,自己在本地记录的状态。那么下面可以讨论一下以前迷惑重重的概念了。

4.为什么服务器都有连接数量的限制?
这里只做讨论。我认为是有两点:

物理带宽的限制,决定了一个时间段内发起连接的数据包不会超过某个数,造成了设备的链接数量的限制。
维持连接需要分配内存等资源,设备的资源有限,决定了一定有个最大连接数的极限。

5.待续
通过连接往外延伸的话题不少,先到此为止吧,有时间再补。

TCP连接详解

通过设置linux参数 net.ipv4.tcp_fin_timeout = 30 ,可以调整
如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决:
编辑文件/etc/sysctl.conf,加入以下内容

tcp 通过序列号q记录已经发送的数据刻度,通过ack记录已经接收的数据量。q记录的是发送的数据,ack记录的是接收的数据量。单位是字节(8bit)

tcp在每次发包时都会计算往复时间及其偏差。将这个往返时间和偏差相加,重发超时时间就是比这个总和要稍大一点的值。
由于最初的数据包还不知道往返时间,所以其重发超时一般设置为6s左右。

在建立tcp连接时,三次握手的时候会计算mss(最大消息长度),建立连接的双方会把自己的接口能适应的mss值放到tcp首部里面发送给对方,最后取较小的那个mss。

tcp窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,窗口大小为4个端。即在收到确认应答之前可以发送的数据的段数。
接收端没有按序列顺序收到数据端时,会不停的发送确认应答,并将当前收到的顺序出问题的数据放到缓冲区。发送端连续三次收到相同序列号的数据段时,会重新发送该段的数据。接收端在接收到遗失的数据的时候会将数据与缓冲区的数据组合,重新按顺序确定ack的序列号,继续接收数据。
tcp窗口的大小是由接收端的处理能力决定的,接收端会在ack的tcp首部中将能处理的窗口大小传给发送端。

拥塞窗口是限制每次发送的数据的大小,初始值是1mss,也就是慢启动。随着正常的收发的进行,拥塞窗口的值会不断的增加。但是不会超过接收端处理窗口的大小。
一开始拥塞窗口每次都会翻倍的增长,在超过慢启动阈值后增长速度会减慢。
增长速率=一个数据段的大小 / 拥塞窗口的大小 *一个数据段的大小
超时重发时,拥塞窗口会变为1mss, 慢启动阈值为原有窗口的一半
重复确认应答时,慢启动阈值为原有窗口的一半,拥塞窗口会变为慢启动阈值+3数据端,

1、已发送的数据收到了ack回执
2、可以发送mss大小的数据时
只有以上两个数据都满足时才发送数据。会有延迟,对延迟敏感的需求可以关。

1、收到2*最大端长度的数据
2、最大延迟0.5s发送确认应答

将tcp的确认应答和回执数据通过一个包发送。
接收数据之后等待应用处理生成返回数据以后在发送回复时同时发送回执。
需要开启延迟确认应答。


本文发布于:2023-02-28 19:52:00,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/167763920970331.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:tcp连接(tcp连接三次握手).doc

本文 PDF 下载地址:tcp连接(tcp连接三次握手).pdf

标签:tcp
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|