这篇文章主要记录一下使用netstat查看tcp连接状态的实例
tcp的连接状态主要是通过三次握手和四次挥手进行状态转移,关于三次握手和四次挥手的详情可以看我的上一篇文章《总结三次握手和四次挥手》
先上一张状态转移图

其中红色线代表客户端的正常状态转换流程
黑色虚线表示服务端的正常状态转换流程
这里看到了其中有几处红色标号,这是几种异常的状态转换,在这里介绍一下(这里还是抽象主动连接一方为客户端,被动连接方为服务端)
-
状态异常转换
标号①:这种状态转移是因为在自己向一方发起SYN连接请求后恰好又收到了来自于另其他方对自己的连接请求,所以这里的状态转移其实是面向其他方连接状态的转移。比如A向B发送连接请求,此时处于SYN_SENT,然后此时又有一个C向A发出连接请求,所以此时A的状态转移为SYN_RCVD。
标号②:这是由于上篇文章提到的四次挥手变为三次挥手,主要是由于客户端发送连接终止报文段之后,恰好服务端的数据发送完毕,然后就把ACK和FIN一同发给了客户端,这里就不存在FIN_WAIT_2状态而直接进入TIME_WAIT状态了。
标号③:这种状态属于一种比较罕见的例外状态,是由于自己发送了FIN和ACK也收到了FIN但是没有收到ACK,一般情况下是ACK和FIN一起收到了,而之所以出现这种状态是由于双方几乎同时发送关闭连接请求,所以进入CLOSING状态,表示都在进行关闭连接,等收到最后一个ACK应答之后进入TIME_WAIT状态。
标号④:这种情况也在之前文章提到过,是由于服务端进入SYN_RCVD状态后在等待ACK确认,但是这个时候如果等不到ACK会进行超时重传,指数增加达到64s后发送RST进行连接中断,或者是第三次握手丢失,服务端收到了来自客户端的数据并认为是非法数据,便会发送RST中断连接。 -
查看网络相关状态信息
○ 命令:netstat
○ 参数:
-a (all)显示所有选项,默认不显示LISTEN相关
-p 显示建立相关链接的程序名
-n 拒绝显示别名,能显示数字的全部转化成数字。
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-l 仅列出有在 Listen (监听) 的服务状态
(1)启动服务器,此时服务器进入监听状态


(2)客户端连接,然后进入ESTABLISHED状态


(3)客户端断开连接,进入TIME_WAIT状态,大约一分钟以后连接断开

(4)服务端发送断开连接请求后,由于客户端数据还未发送完,此时服务端进入FIN_WAIT2,等待客户端的FIN请求,客户端进入CLOSE_WAIT,发送完数据后进行FIN请求。此时重启服务端的时候显示端口被占用,是因为上个连接还未关闭。


(5)客户端发送完数据之后连接断开,在使用netstat查看不到连接状态

由于知识有限,加上三次连接的过程是通过内核完成的,所以捕捉不到全部的过程,但是也可以通过这几个例子查看到netstat确实可以查看连接所达到的状态,这也是学习状态转移的意义之一,通过这种方法,当连接出现异常时可以进行查看。
最后上一下服务端和客户端的代码,有兴趣的可以自己尝试下
- 服务端代码
// 并发的服务器代码,父进程监听后fork子进程进行通信
#include <stdio.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
//信号捕捉处理函数
void child_handle(int num)
{
pid_t pid;
while((pid=waitpid(-1,NULL,WNOHANG))>0)
{
printf("child has handled pid=%d\n",pid);
}
}
int main(

本文通过实例介绍如何利用netstat命令查看TCP连接状态,包括正常和异常状态转换,如SYN_SENT、SYN_RCVD、ESTABLISHED、TIME_WAIT等,并探讨了TCP连接的三次握手和四次挥手过程。通过分析,可以更好地理解网络连接中可能出现的问题。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



