break; case (TcpControlBits.Fin | TcpControlBits.Acknowledgment): if (tcpStatus == TCPStatus.FIN_WAIT_1) { Utils.PacketInfoPrinter(packet, tcpStatus); } else if (tcpStatus == TCPStatus.LAST_ACK) { Utils.PacketInfoPrinter(packet, tcpStatus); } break; case TcpControlBits.Acknowledgment: if (tcpStatus == TCPStatus.TIME_WAIT) { Utils.PacketInfoPrinter(packet, tcpStatus); }else if (tcpStatus == TCPStatus.CLOSE_WAIT) { Utils.PacketInfoPrinter(packet, tcpStatus); Packet fin = Utils.BuildTcpPacket(endPointInfo, TcpControlBits.Fin | TcpControlBits.Acknowledgment); communicator.SendPacket(fin); tcpStatus = TCPStatus.LAST_ACK; }break; default: Utils.PacketInfoPrinter(packet); break; } } break; default:
throw new InvalidOperationException("The result " + result + " should never be reached here");
}
} while (running);
}

对于客户端,通过Python实现了一个简单的Socket程序来模拟客户端行为:

from socket import *
import time
HOST = "192.168.56.101"
PORT = 3333
BUFSIZ = 1024
ADDR = (HOST, PORT)
client = socket(AF_INET, SOCK_STREAM)
client.connect(ADDR)
time.sleep(5)
client.close()

运行效果

这次,宿主机上运行的是服务端,虚拟机运行的是客户端,打开Wireshark监听"VirtualBox Host-Only Network"网卡,并设置filter为"port 3333"。

运行服务端程序,服务端将处于监听状态。这是在虚拟机中运行"client.py"。这时,通过服务端console可以看到客户端和服务端之间的包,以及服务端的状态变迁。

 

Wireshark依然显示的是TCP连接建立和终止的过程。

 

netstat命令

netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。

实验中的宿主机系统是Win7,下面看看通过 netatat /? 获得的帮助信息:

 

netstat命令失效?

虽然说上面的程序可以打印出服务端的状态变迁过程,但是这次让我们通过netstat命令查看一下。

为了方便查看,将"client.py"中的"time.sleep(5)"改为"time.sleep(300)",使客户端跟服务器之间的连接保持300秒。客户端的端口号为"1090"。

 

这时,分别在服务端和客户端cmd窗口中执行 netstat -anp TCP | findstr "192.168.56" 命令,查看包含"192.168.56"字符串的TCP连接:

服务端:

 

客户端:

 

为什么服务端看不到TCP连接?就像我们第一篇介绍的那样,Pcap.Net是不经过操作系统协议栈的,所以这也就解释了为什么"netstat"命令发现不了服务端的TCP连接。

等300秒结束后,客户端会发送终止连接请求。当连接终止后,可以看大客户端的TCP连接状态变成了"TIME_WAIT"。

客户端:

 

总结

本文中根据TCP状态变迁图,得到了服务端的状态变迁表。

然后使用Pcap.Net,基于服务端的状态变迁表,构建了一个简单的服务端,展示了服务端状态变迁的过程。

文中还简单的介绍了"netstat"命令,通过这个命令可以查看TCP连接的状态,结合这个命令,可以更好的了解TCP状态。




相关内容