动手学习TCP系列之TCP连接建立与终止(1)(3)
在PacketHandler函数中用到了BuildTcpResponsePacket这个函数,这个函数根据收到的TCP包,来构建response包。
这个函数有下面几个注意点:
该函数会根据收到的包,设置response包的源和目的地址
该函数会接受PacketHandler传递来的TCP flags,并设置到TCP首部中
该函数的另一个重要部分就是会计算并设置TCP首部中的seq好ack号,这一点很重要
public static Packet BuildTcpResponsePacket(Packet packet, TcpControlBits tcpControlBits) { EthernetLayer ethernetHeader = new EthernetLayer { Source = new MacAddress(packet.Ethernet.Destination.ToString()), Destination = new MacAddress(packet.Ethernet.Source.ToString()), EtherType = EthernetType.None, // Will be filled automatically. }; IpV4Layer ipHeader = new IpV4Layer { Source = new IpV4Address(packet.Ethernet.IpV4.Destination.ToString()), CurrentDestination = new IpV4Address(packet.Ethernet.IpV4.Source.ToString()), Fragmentation = IpV4Fragmentation.None, HeaderChecksum = null, // Will be filled automatically. Identification = 123, Options = IpV4Options.None, Protocol = null, // Will be filled automatically. Ttl = 100, TypeOfService = 0, }; TcpLayer tcpHeader = new TcpLayer { SourcePort = packet.Ethernet.IpV4.Tcp.DestinationPort, DestinationPort = packet.Ethernet.IpV4.Tcp.SourcePort, Checksum = null, // Will be filled automatically. SequenceNumber = seqNum = packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber, AcknowledgmentNumber = ackNum = packet.Ethernet.IpV4.Tcp.SequenceNumber + (uint)((packet.Ethernet.IpV4.Tcp.Payload.Length > 0) ? packet.Ethernet.IpV4.Tcp.Payload.Length : 1), ControlBits = tcpControlBits, Window = windowSize, UrgentPointer = 0, Options = TcpOptions.None, }; PacketBuilder builder = new PacketBuilder(ethernetHeader, ipHeader, tcpHeader); return builder.Build(DateTime.Now); }
运行效果
打开Wireshark监听"VirtualBox Host-Only Network"网卡,并设置filter为"port 8081"。
然后运行程序,通过console可以看到客户端发送的包,以及服务端返回的包,通过这些包完成了TCP连接的建立和终止。
下面是Wireshark中显示的结果,Wireshark比较友好,会显示相对seq号,所以看到的都是从0开始编号。
注意seq号和ack号的变化,[SYN]和[FIN]标志的TCP包都会消耗一个序号。
总结
本文介绍了TCP首部,通过设置TCP首部中的[SYN]标志,可以构造TCP连接建立请求包;通过设置[FIN]标志,可以构造TCP连接终止请求包。
文中使用Pcap.Net构建了一个简单的客户端,完成了向服务器建立(三次握手)和终止(四次挥手)连接的过程。
通过这个实验,一定会对TCP连接的建立和终止有一个比较直观的认识。
评论暂时关闭