tcp连接状态详解
unix的哲学是一切皆文件,可以把socket看成是一种特殊的文件,而一些socket函数就是对其进行的操作api(读/写IO、打开、关闭)。我们知道普通文件的打开操作(open)返回一个文件描述字,与之类似,socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。当我们调用socket创建一个socket时,返回的socket描述字它存在于协议族(address family,AF_XXX)空间中,但没有一个具体的地址。如果想要给它赋值一个地址,就必须调用bind()函数,sockfd即socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这个描述字绑定一个名字。在将一个地址绑定到socket的时候,需要先将主机字节序转换成为网络字节序,而不要假定主机字节序跟网络字节序一样使用的是Big-Endian。由于这个问题曾引发过不少血案,谨记对主机字节序不要做任何假定,务必将其转化为网络字节序再赋给socket。这里的主机字节序就是我们平常说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。引用标准的Big-Endian和Little-Endian的定义如下:listen函数的第一个参数即为要监听的socket描述字,第二个参数为socket可以接受的排队的最大连接个数。listen函数表示等待客户的连接请求。connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接。TCP服务器端依次调用socket()、bind()、listen()之后,就会监听指定的socket地址了。TCP客户端依次调用socket()、connect()之后就向TCP服务器发送连接请求。TCP服务器监听到这个请求之后,就会调用accept()函数去接收请求,这样连接就建立好了(在connect之后就建立好了三次连接),之后就可以开始进行类似于普通文件的网络I/O操作了。如果accpet成功,那么其返回值是由内核自动生成的一个全新的描述字,代表与客户的TCP连接。accept的第一个参数为服务器的socket描述字,是服务器开始调用socket()函数生成的,称为监听socket描述字;而accept函数返回的是已连接的socket描述字。一个服务器通常通常仅仅只创建一个监听socket描述字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建了一个已连接socket描述字,当服务器完成了对某个客户的服务,相应的已连接socket描述字就被关闭。read函数是负责从fd中读取内容.当读成功时,read返回实际所读的字节数,如果返回的值是0表示已经读到文件的结束了,小于0表示出现了错误。如果错误为EINTR说明读是由中断引起的,如果是ECONNREST表示网络连接出了问题。write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数。失败时返回-1,并设置errno变量。 在网络程序中,当我们向套接字文件描述符写时有俩种可能。1)write的返回值大于0,表示写了部分或者是全部的数据。2)返回的值小于0,此时出现了错误在服务器与客户端建立连接之后,会进行一些读写操作,完成了读写操作就要关闭相应的socket描述字,类似于操作完打开的文件要调用fclose关闭打开的文件。close一个TCP socket的缺省行为时把该socket标记为已关闭,然后立即返回到调用进程。该描述字不能再由调用进程使用,也就是说不能再作为read或write的第一个参数close操作只是使相应socket描述字的引用计数-1,只有当引用计数为0的时候,才会触发TCP客户端向服务器发送终止连接请求。我们知道tcp建立连接要进行“三次握手”,即交换三个分组。大致流程如下:客户端向服务器发送一个SYN J服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1客户端再想服务器发一个确认ACK K+1socket中TCP的四次握手释放连接详解某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。一段时间之后,服务端调用close关闭它的socket。这导致它的TCP也发送一个FIN N;接收到这个FIN的源发送端TCP对它进行确认,这样每个方向上都有一个FIN和ACK。为什么要三次握手由于tcp连接是全双工的,存在着双向的读写通道,每个方向都必须单独进行关闭。当一方完成它的数据发送任务后就可以发送一个FIN来终止这个方向的连接。收到FIN只意味着这个方向上没有数据流动,但并不表示在另一个方向上没有读写,所以要双向的读写关闭需要四次握手,3. time_wait状态如何避免?首先服务器可以设置SO_REUSEADDR套接字选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口。在一个非常有用的场景就是,如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一端口,此时SO_REUSEADDR选项就可以避免TIME_WAIT状态。1.客户端连接服务器的80服务,这时客户端会启用一个本地的端口访问服务器的80,访问完成后关闭此连接,立刻再次访问服务器的80,这时客户端会启用另一个本地的端口,而不是刚才使用的那个本地端口。原因就是刚才的那个连接还处于TIME_WAIT状态。2.客户端连接服务器的80服务,这时服务器关闭80端口,立即再次重启80端口的服务,这时可能不会成功启动,原因也是服务器的连接还处于TIME_WAIT状态。实战分析:状态描述:CLOSED:无连接是活动的或正在进行LISTEN:服务器在等待进入呼叫SYN_RECV:一个连接请求已经到达,等待确认SYN_SENT:应用已经开始,打开一个连接ESTABLISHED:正常数据传输状态FIN_WAIT1:应用说它已经完成FIN_WAIT2:另一边已同意释放ITMED_WAIT:等待所有分组死掉CLOSING:两边同时尝试关闭TIME_WAIT:另一边已初始化一个释放LAST_ACK:等待所有分组死掉命令解释:如何尽量处理TIMEWAIT过多?编辑内核文件/etc/sysctl.conf,加入以下内容:net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。net.ipv4.tcp_fin_timeout 修改系默认的 TIMEOUT 时间然后执行 /sbin/sysctl -p 让参数生效./etc/sysctl.conf是一个允许改变正在运行中的Linux系统的接口,它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,修改内核参数永久生效。简单来说,就是打开系统的TIMEWAIT重用和快速回收。本文主要讲述了socket的主要api,以及tcp的连接过程和其中各个阶段的连接状态,理解这些是更深入了解tcp的基础!

如何释放长链接的端口
TCP 传输链接的释放当 TCP 连接建立以后,就可以在两个方向传送数据流。当 TCP 的网络应用进程再没有数据需要发送的时候,就可以发出关闭连接命令,释放连接。TCP 是通过发送 FIN 字段置1的数据段来作为关闭传输连接的命令,从而关闭本端数据流的,但是本端仍还可以继续接收来自对端的数据,直到对端也使用了同样的方法关闭那个方向的数据流为止,,这时整个双方传输连接就彻底关闭了。单方面主动关闭的 TCP 连接释放过程相对 TCP 传输连接建立的三次握手过程来说,TCP 传输连接的释放过程要稍微复杂一些,需要经过四次握手过程。这是由 TCP 的半关闭(half-closed)特性造成的,因为这一个 TCP 连接是全双工(即数据在两个方向上能同时传递),每个方向必须单独进行关闭。TCP 传输连接关闭原则如下:当一端完成它的数据发送任务后就可以发送一个 FIN 字段值置1的数据段来终止这个方向的数据发送;当另一端收到这个 FIN 数据段后,必须通知它的应用层“对端已经终止了这个方向的数据发送”。而 FIN 数据段的发送是由应用层调用 CLOSE 服务原语的结果。TCP 连接释放的四次握手过程如下图所示,具体描述如下。TCP传输连接释放的四次握手过程一开始,通信双方都处于 ESTABLISHED (连接建立)状态。如果客户端认为数据全部发送完了,想结束本次传输连接,则由应用层的对应应用调用 CLOSE 服务原语,然后向服务器发送一个 FIN 字段值置1的数据段(假设此数据段的序号为m),客户端进入 FIN WAIT 1 状态,等待服务器的确认。服务器在收到客户端发来的 FIN 数据之后,确认客户端没有新的数据要发送了,向客户端发送一个 ACK 字段值置1、确认号为 m+1 的数据段(假设此数据段的序号为 w,服务端与客户端的数据段序号可以不一样),表示前面的数据已全部收到了,然后进入 CLOSE WAIT (关闭等待)状态。与此同时,服务器的TCP实体通知对应的应用进程,释放从客户端到服务器方向的传输连接,进入半关闭状态。但此时服务器仍可以向客户端发送数据段,客户端也可以接受来自服务器的数据,而且这可能持续一段时间,直到服务器的数据也全部发送完毕。当客户端收到服务器的 ACK 数据段之后,进入 FIN WAIT 2 状态,进一步等待服务器发出连接释放的数据段。当服务器发送完全部的数据后,其对应的应用进程也会通知 TCP 实体释放此方向的TCP传输连接,向客户端发送 FIN 字段置1、ack = m+1(假设此时的数据段序号已变为 w)的确认数据段。这时服务器进入 LAST ACK (最后确认)状态,等待客户端的确认。客户端在收到服务器的 FIN+ACK 数据段后,,向服务发送一个 ACK 字段值为1、ack = w+1、序号为m+1 的数据段,进入 TIME WAIT 状态。但此时 TCP 连接还没有释放,必须等待 2MSL 时间(RFC793 建议设置 MSL 为2分钟)后,客户端才进入到 CLOSED 状态,彻底释放了 TCP 连接。服务器在接收到客户端发来的 ACK 数据段后,也进入 CLOSED, 彻底释放连接。此时,已经完成了这个 TCP 传输连接过程。双方主动关闭的 TCP 连接释放流程与可以双方同时建立 TCP 传输连接一样,TCP 传输连接关闭也可以由双方同时主动进行(正常情况下都是由一方发送第一个 FIN 数据段进行主动连接关闭,另一方被动接受连接关闭),如下图所示。具体描述如下。主动同时关闭TCP连接过程当两端对应的网络应用层进程同时调用 CLOSE 原语,并发送 FIN 数据段执行关闭命令时,两端均从 ESTABLISHED 状态转变为 FIN WAIT 1 状态。任意一端收到对端发来的 FIN 数据段后,其状态均由 FIN WAIT 1 转变到 CLOSING 状态,并发送最后的 ACK 数据段。当收到最后的 ACK 数据段后,状态转变为 TIME_WAIT,在等待 2MSL 后进入到 CLOSED 状态,最终释放这个TCP连接。

tcp四次握手释放连接是怎么实现的
RST 就是用来重置连接的,一般是当发送端发现了异常时。接收端收到后会断开连接;而 ACK 用来确认之前接受的数据 你可以试试只关闭页面,不退出浏览器,看看有没有正常的四次挥手过程

tcp是怎么建立连接和释放连接的
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)Sequence number(顺序号码) Acknowledge number(确认号码)第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。 完成三次握手,主机A与主机B开始传送数据。
TCP协议建立连接的过程: 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

简述TCP连接与释放过程
A向B发送SYN B向A发送SYN+ACKA向B发送ACK,链接建立A向B发送FINB向A发送FIN+ACKA向B发送ACK B向A发送ACK链接断开

本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/319964.html。