netstat是一个功能很强大的网络信息统计工具。它可以打印本地网卡接口上的全部连接、路由表信息、网卡接口信息等。我们主要利用的是上述功能中的第一个,即显示TCP连接及其状态信息。毕竟,要获得路由表信息和网卡接口信息,我们可以使用输出内容更丰富的route和ifconfig命令。
netstat命令常用的选项如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/b5f961d998474a2aa65485a3485a29fc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARHV0a2ln,size_20,color_FFFFFF,t_70,g_se,x_16)
为了深入学习这一命令,也为了演示上一节存在的粘包问题,我们继续使用之前的代码:服务器循环接收数据,客户端循环发送数据:
![在这里插入图片描述](https://img-blog.csdnimg.cn/fa97d459891e4a21aa1ccbd5d9f590dc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARHV0a2ln,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/0c9c6f74b7dd4651bbe04a2de38bc462.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARHV0a2ln,size_20,color_FFFFFF,t_70,g_se,x_16)
我们将服务器端的代码修改为,一次只接收一个字符的数据:
while(1) // 循环接收不同客户端的链接
{
int len = sizeof(saddr);
int c = accept(sockfd,(syruct sockaddr*)&caddr,&len);
if(c == -1)
{
printf("Get one client link fail\n");
continue;
}
while(1) //循环和一个客户端通讯
{
char buff[128] = {0};
///
int n = recv(c, buff, 1, 0);
///
if(n <= 0)
{
printf("client will unlink\n");
break;
}
printf("buff = :%s\n", buff);
send(c, "OK", 2, 0); //也可以用write
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/574655a3399e4167a22ce097b7b0c59b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARHV0a2ln,size_20,color_FFFFFF,t_70,g_se,x_16)
因此,我们可以理解为:服务器端的代码,每收一次数据就给客户端发哦送一个ok,但是为什么我们只收到了一个ok呢,不是应该收到6个ok吗?
这时候,我们通过这个命令netstat查看
![在这里插入图片描述](https://img-blog.csdnimg.cn/2d8a9c832de44661b65b199e9af9e1ba.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARHV0a2ln,size_20,color_FFFFFF,t_70,g_se,x_16)
其中,Recv-Q是接收缓冲区,Send-Q是发送缓冲区, Local是本地IP和端口,Foregn是对方的IP和端口
我们刚才说:服务器应该给客户端回复6个ok,我们看到图中cli的接收缓冲区,有10字节,就是剩下的5个ok。
如果我们现在再给服务器发送数据,就会把此时缓冲区的5个ok读出来
![在这里插入图片描述](https://img-blog.csdnimg.cn/e9cf30ab37ed47da9f706b6d10765039.png)
然后a和\n到达服务器后,服务器发送2个ok,这2个ok在客户端的接收缓冲区中。
![请添加图片描述](https://img-blog.csdnimg.cn/6b7886ff3c8f43ffab1ac245500269ab.png)
这就是粘包问题,对方send好几次,客户端一次性读到。