Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1765409
  • 博文数量: 293
  • 博客积分: 10574
  • 博客等级: 上将
  • 技术积分: 5085
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-22 17:00
文章分类

全部博文(293)

文章存档

2011年(27)

2010年(84)

2009年(62)

2008年(120)

我的朋友

分类: LINUX

2011-03-23 18:39:31

tcp状态:
LISTEN:侦听来自远方的TCP端口的连接请求
SYN-SENT:在发送连接请求后等待匹配的连接请求
SYN-RECEIVED:在收到和发送一个连接请求后等待对方对连接请求的确认
ESTABLISHED:代表一个打开的连接
FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN-WAIT-2:从远程TCP等待连接中断请求
CLOSE-WAIT:等待从本地用户发来的连接中断请求
CLOSING:等待远程TCP对连接中断的确认
LAST-ACK:等待原来的发向远程TCP的连接中断请求的确认
TIME-WAIT:等待足够的时间以确保远程TCP接收到连接中断请求的确认
CLOSED:没有任何连接状态

TCP是一个面向连接的协议,所以在连接双方发送数据之前,都需要首先建立一条连接。这和前面讲到的协议完全不同。前面讲的所有协议都只是发送数据而已, 大多数都不关心发送的数据是不是送到,UDP尤其明显,从编程的角度来说,UDP编程也要简单的多----UDP都不用考虑数据分片。
书中用telnet登陆退出来解释TCP协议连接的建立和中止的过程,可以看到,TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手
1.连接的建立
在建立连接的时候,客户端首先向服务器申请打开某一个端口(用SYN段等于1的TCP报文),然后服务器端发回一个ACK报文通知客户端请求报文收到,客 户端收到确认报文以后再次发出确认报文确认刚才服务器端发出的确认报文(绕口么),至此,连接的建立完成。这就叫做三次握手。如果打算让双方都做好准备的 话,一定要发送三次报文,而且只需要三次报文就可以了。
可以想见,如果再加上TCP的超时重传机制,那么TCP就完全可以保证一个数据包被送到目的地。
2.结束连接
TCP有一个特别的概念叫做half-close,这个概念是说,TCP的连接是全双工(可以同时发送和接收)连接,因此在关闭连接的时候,必须关闭传和 送两个方向上的连接。客户机给服务器一个FIN为1的TCP报文,然后服务器返回给客户端一个确认ACK报文,并且发送一个FIN报文,当客户机回复 ACK报文后(四次握手),连接就结束了。
3.最大报文长度
在建立连接的时候,通信的双方要互相确认对方的最大报文长度(MSS),以便通信。一般这个SYN长度是MTU减去固定IP首部和TCP首部长度。对于一 个以太网,一般可以达到1460字节。当然如果对于非本地的IP,这个MSS可能就只有536字节,而且,如果中间的传输网络的MSS更佳的小的话,这个 值还会变得更小。
4.TCP的状态迁移图
状态迁移图



书P182页给出了TCP的状态图,这是一个看起来比较复杂的状态迁移图,因为它包含了两个部分---服务器的状态迁移和客户端的状态迁移,如果从某一个 角度出发来看这个图,就会清晰许多,这里面的服务器和客户端都不是绝对的,发送数据的就是客户端,接受数据的就是服务器。】


详细分析
4.1.客户端应用程序的状态迁移图
客户端的状态可以用如下的流程来表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
以上流程是在程序正常的情况下应该有的流程,从书中的图中可以看到,在建立连接时,当客户端收到SYN报文的ACK以后,客户端就打开了数据交互地连接。 而结束连接则通常是客户端主动结束的,客户端结束应用程序以后,需要经历FIN_WAIT_1,FIN_WAIT_2等状态,这些状态的迁移就是前面提到 的结束连接的四次握手。

4.2.服务器的状态迁移图
服务器的状态可以用如下的流程来表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
在建立连接的时候,服务器端是在第三次握手之后才进入数据交互状态,而关闭连接则是在关闭连接的第二次握手以后(注意不是第四次)。而关闭以后还要等待客户端给出最后的ACK包才能进入初始的状态。

4.3.其他状态迁移
书中的图还有一些其他的状态迁移,这些状态迁移针对服务器和客户端两方面的总结如下
  • LISTEN->SYN_SENT,对于这个解释就很简单了,服务器有时候也要打开连接的嘛。
  • SYN_SENT->SYN收到,服务器和客户端在SYN_SENT状态下如果收到SYN数据报,则都需要发送SYN的ACK数据报并把自己的状态调整到SYN收到状态,准备进入ESTABLISHED
  • SYN_SENT->CLOSED,在发送超时的情况下,会返回到CLOSED状态。
  • SYN_收到->LISTEN,如果受到RST包,会返回到LISTEN状态。
  • SYN_收到->FIN_WAIT_1,这个迁移是说,可以不用到ESTABLISHED状态,而可以直接跳转到FIN_WAIT_1状态并等待关闭。

  • 4.4.2MSL等待状态
    TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间(MSL,Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。我们知道这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。
      RFC 793 指出MSL为2min。然而,实现中的常用值是30s,1min,或2min。我们知道在实际应用中,对IP数据报TTL的限制是基于跳数,而不是定时器。对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。
      这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的套接字对(客户的I P地址和端口号,服务器的IP地址和端口号)不能再被使用,前一替身的任何迟到报文将被丢弃,这样做的目的是防止迟到的报文被新连接曲解而干扰新的连接,所以,这个连接只能在2MSL结束后才能再被使用。这里存在的一个例外的情况,即当新连接SYN段的ISN序号大于这个连接前一个替身的最后序号时,TCP可以立即从TIME_WAIT状态恢复并开始接受这个新连接。(一个连接由一个套接字对来定义。一个连接的新的实例称为该连接的替身)。

  • 书中给的图里面,有一个TIME_WAIT等待状态,这个状态又叫做2MSL状态,说的是在FIN_WAIT2发送了最后一个ACK数据报以后,要进入 TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在 很大程度上保证了双方都可以正常结束,但是,问题也来了。
    由于插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些, 但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错 误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。

  • 4.5.FIN_WAIT_2状态
    这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据, 但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态。
    5.RST,同时打开和同时关闭
    RST是另一种关闭连接的方式,应用程序应该可以判断RST包的真实性,即是否为异常中止。而同时打开和同时关闭则是两种特殊的TCP状态,发生的概率很小。

  • 6.TCP服务器设计
    前面曾经讲述过UDP的服务器设计,可以发现UDP的服务器完全不需要所谓的并发机制,它只要建立一个数据输入队列就可以。但是TCP不同,TCP服务器 对于每一个连接都需要建立一个独立的进程(或者是轻量级的,线程),来保证对话的独立性。所以TCP服务器是并发的。而且TCP还需要配备一个呼入连接请 求队列(UDP服务器也同样不需要),来为每一个连接请求建立对话进程,这也就是为什么各种TCP服务器都有一个最大连接数的原因。而根据源主机的IP和 端口号码,服务器可以很轻松的区别出不同的会话,来进行数据的分发。

  • 补图





    -----------------------------------------------------------------------------
     
     
     
                         

    --------------------------------------------------------------

    TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题

    TCP状态迁移
    大家对netstat -a命令很熟悉,但是,你有没有注意到STATE一栏呢,基本上显示着established,time_wait,close_wait等,这些到底是 什么意思呢,在这篇文章,我将会详细的阐述。
    大家很明白TCP初始化连接三次握手吧:发SYN包,然后返回SYN/ACK包,再发ACK包,连接正式建立。但是这里有点出入,当请求者收到SYS /ACK包后,就开始建立连接了,而被请求者第三次握手结束后才建立连接。但是大家明白关闭连接的工作原理吗?关闭连接要四次握手:发FIN包,ACK 包,FIN包,ACK包,四次握手!!为什么呢,因为TCP连接是全双工,我关了你的连接,并不等于你关了我的连接。

    客户端TCP状态迁移:
    CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
    服务器TCP状态迁移:
    CLOSED->LISTEN->SYN收到 ->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

    当客户端开始连接时,服务器还处于LISTENING,
    客户端发一个SYN包后,他就处于SYN_SENT状态,服务器就处于SYS收到状态,
    然后互相确认进入连接状态ESTABLISHED.


    当客户端请求关闭连接时,客户端发送一个FIN包后,客户端就进入FIN_WAIT_1状态,等待对方的确认包,
    服务器发送一个ACK包给客户,客户端收到ACK包后结束FIN_WAIT_1状态,进入FIN_WAIT_2状态,等待服务器发过来的关闭请求,
    服务器发一个FIN包后,进入CLOSE_WAIT状态,
    当客户端收到服务器的FIN包,FIN_WAIT_2状态就结束,然后给服务器端的FIN包给以一个确认包,客户端这时进入TIME_WAIT,
    当服务器收到确认包后,CLOSE_WAIT状态结束了,
    这时候服务器端真正的关闭了连接.但是客户端还在TIME_WAIT状态下,

    什么时候结束呢.我在这里再讲到一个新名词:2MSL等待状态,其实TIME_WAIT就是2MSL等待状态,
    为什么要设置这个状态,原因是有足够的时间让ACK包到达服务器端,如果服务器端没收到ACK包,超时了,然后重新发一个FIN包,直到服务器收到ACK 包.

    TIME_WAIT状态等待时间是在TCP重新启动后不连接任何请求的两倍.
    大家有没有发现一个问题:如果对方在第三次握手的时候出问题,如发FIN包的时候,不知道什么原因丢了这个包,然而这边一直处在FIN_WAIT_2状 态,而且TCP/IP并没有设置这个状态的过期时间,那他一直会保留这个状态下去,越来越多的FIN_WAIT_2状态会导致系统崩溃.

    上面我碰到的这个问题主要因为TCP的结束流程未走完,造成连接未释放。现设客户端主动断开连接,流程如下

    如上图所示,

    Client                            消息                                    Server

             close()
    ------ FIN ------->
    FIN_WAIT1                                                         CLOSE_WAIT
    <----- ACK -------
    FIN_WAIT2
    close()
    <------ FIN ------                    
    TIME_WAIT                                                       LAST_ACK      

                                          ------ ACK ------->
    CLOSED
    CLOSED


    由于Server的Socket在客户端已经关闭时而没有调用关闭,
    造成服务器端的连接处在“挂起”状态,而客户端则处在等待应答的状态上。
    此问题的典型特征是:
    一端处于FIN_WAIT2 ,而另一端处于CLOSE_WAIT.

    不过,根本问题还是程序写的不好,有待提高

    -------------------------------------------------------------------------

    CLOSE_WAIT,TCP的癌症,TCP的朋友。

    CLOSE_WAIT状态的生成原因
    首先我们知道,如果我们的服务器程序APACHE处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!

    因为如果是CLIENT端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:

    Client ---> FIN ---> Server

    Client <--- ACK <--- Server

    这时候Client端处于FIN_WAIT_2状态;而Server 程序处于CLOSE_WAIT状态。

    Client <--- FIN <--- Server

    这时Server 发送FIN给Client,Server 就置为LAST_ACK状态。

    Client ---> ACK ---> Server

    Client回应了ACK,那么Server 的套接字才会真正置为CLOSED状态。

    Server 程序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Client,那么可能是在关闭连接之前还有许多数据要发送或者其 他事要做,导致没有发这个FIN packet。

    通常来说,一个CLOSE_WAIT会维持至少2个小时的时间。如果有个流氓特地写了个程序,给你造成一堆的 CLOSE_WAIT,消耗你的资源,那么通常是等不到释放那一刻,系统就已经解决崩溃了。

    只能通过修改一下TCP/IP的参数,来缩短这个时间:修改tcp_keepalive_*系列参数有助于解决这个 问题。

    解决这个问题的方法是修改系统的参数,系统默认超时时间的是7200秒,也就是2小时, 这个太大了,可以修改如下几个参数:

    sysctl -w net.ipv4.tcp_keepalive_time=30
    sysctl -w net.ipv4.tcp_keepalive_probes=2
    sysctl -w net.ipv4.tcp_keepalive_intvl=2

    然后,执行sysctl命令使修改生效。

    连接进程是通过一系列状态表示的,这些状态有:
    LISTEN,SYN-SENT,SYN-RECEIVED,ESTABLISHED,FIN-WAIT-1,FIN-WAIT-2,CLOSE- WAIT,CLOSING,LAST-ACK,TIME-WAIT和CLOSED。

    各个状态的意义如下:
    LISTEN - 侦听来自远方TCP端口的连接请求;
    SYN-SENT -在发送连接请求后等待匹配的连接请求;
    SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认;
    ESTABLISHED- 代表一个打开的连接,数据可以传送给用户;
    FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
    FIN-WAIT-2 - 从远程TCP等待连接中断请求;
    CLOSE-WAIT - 等待从本地用户发来的连接中断请求;
    CLOSING -等待远程TCP对连接中断的确认;
    LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;
    TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认;
    CLOSED - 没有任何连接状态;

    TCP连接过程是状态的转换,促使发生状态转换的是用户调用:
    OPEN,SEND,RECEIVE,CLOSE,ABORT和STATUS;
    传送过来的数据段,特别那些包括以下标记的数据段SYN,ACK,RST和FIN;
    还有超时,上面所说的都会时TCP状态发生变化。

    TCP连接的状态转换图

    n多人都 知道,排除和定 位网络或系统故障大有帮助,但是怎牢牢地这张图刻在中呢?那你就一定要对 这张图一个状态,及转换的过程有深刻地认识,不能只停留在一知半解之中。下面对这张图的11种状 态详细解释一下,以便加强记忆!不过在这之前,先回顾一下TCP建立连接的三次握手过程,以及关闭连接的四次握手过程。

    1、建立连接协议(三次握手)
    1)客户 端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1

    2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标 志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通 讯。

    3) 客户必须再次回应服务段一个ACK报文,这是报文段3

    2、连接终止协议(四次握手)
       由于TCP连 接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终 止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接 在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

     (1 TCP客 户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。
     (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一 样,一个FIN将占用一个序号。
     (3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。
     (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

    CLOSED: 这个没什么好说的了,表示初始状态。

    LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处 于监听状态,可以接受连接了。

    SYN_RCVD: 这个状态表示接受到了SYN报 文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手 过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文 后,它会进入到ESTABLISHED状态。

    SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

    ESTABLISHED:这个容易理解了,表示连接已经建立了。

    FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报 文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKETESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况 下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

    FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点 数据需要传送给你,稍后再关闭连接。

    TIME_WAIT: 表示收到了对方的FIN报 文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标 志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

    CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发 送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报 文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报 文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一 个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

    CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一 个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文 给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话, 那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

    LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报 文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

    最后有2个问题 的回答,我自己分析后的结论(不一定保证100%正确)

    1、 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

    这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACKSYNACK起 应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文 通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文 和FIN报文多数情况下都是分开发送的。

    2、 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状 态?

    这是因为:虽然双方 都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状 态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报 文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报 文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报 文,并保证于此。


            断开连接的时候, 当发起主动关闭的左边这方发送一个FIN过去后,
    右边被动关闭的这方要回应一个ACK,这个ACK是TCP回应的,而不是应用程序发送的,
    此时,被动关闭的一方就处于CLOSE_WAIT状态了。


    如果此时被动关闭的这一方不再继续调用closesocket,那么他就不会发送接下来的FIN,导致自己老是处于CLOSE_WAIT。
    只有被动关闭的这一方调用了 closesocket,才会发送一个FIN给主动关闭的这一方,同时也使得自己的状态变迁为LAST_ACK。

    比如被动关闭的是客户端.

    当对方调用closesocket的时候,你的程序正在

    int nRet = recv(s,....);
    if (nRet == SOCKET_ERROR)
    {
    // closesocket(s);
    return FALSE;
    }

    很多人就是忘记了那句closesocket,这种代码太常见了。
    我的理解,
    当主动关闭的一方发送FIN到被动关闭这边后,被动关闭这边的TCP马上回应一个ACK过去,同时向上面应用程序提交一个ERROR,
    导致上面的SOCKET的send或者recv返回SOCKET_ERROR.

    正常情况下,如果上面在返回SOCKET_ERROR后调用了closesocket, 那么被动关闭的者一方的TCP就会发送一个FIN过去,自己的状态就变迁到LAST_ACK.


    服务器上出现大量的close_wait的例子和解决方法(例子从网上找的,基本差不多)

    oracle9i]$ /usr/sbin/lsof -i | grep 6800
    oracle    22725 oracle9i    3u IPv4 18621468       TCP RHEL3:6800 (LISTEN)
    oracle    22725 oracle9i    4u IPv4 18621469       TCP RHEL3:6800->RHEL3:2174 (CLOSE_WAIT)
    oracle    22725 oracle9i    8u IPv4 18621568       TCP RHEL3:6800->RHEL3:2175 (CLOSE_WAIT)
    oracle    22725 oracle9i    9u IPv4 18621578       TCP RHEL3:6800->RHEL3:2176 (CLOSE_WAIT)
    oracle    22726 oracle9i    3u IPv4 18621468       TCP RHEL3:6800 (LISTEN)
    oracle    22726 oracle9i    4u IPv4 18621469       TCP RHEL3:6800->RHEL3:2174 (CLOSE_WAIT)
    oracle    22726 oracle9i    8u IPv4 18621568       TCP RHEL3:6800->RHEL3:2175 (CLOSE_WAIT)
    oracle    22726 oracle9i    9u IPv4 18621578       TCP RHEL3:6800->RHEL3:2176 (CLOSE_WAIT)

    [oracle9i@RHEL3 oracle9i]$ kill -9 22725

    # 22725, 22726就是使用该6800端口的进程号(PID)。
    [oracle9i@RHEL3 oracle9i]$ /usr/sbin/lsof -i | grep 6800

    进程被kill时,会释放占用的所有链接句柄。

    转自:

    阅读(1017) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~