当我使用TCPIP连接与[FIN,PSH,ACK]发送字符串时,如何生成[FIN]标志



我正在尝试模拟一个与现有服务器对话的客户端程序。我用过wireshark,可以看到来回的信息。客户端程序-连接并发送字符串

9 0 0 99 3 0 CR LF 
CLIENT SEND
0.001157    192.168.0.210   192.168.0.197   TCP 69  61517 → 22223 [PSH, ACK] Seq=1 Ack=1 Win=131328 Len=15

然后一个空字符串只是

CR LF
0.001232    192.168.0.210   192.168.0.197   TCP 56  61517 → 22223 [FIN, PSH, ACK] Seq=16 Ack=1 Win=131328 Len=2

服务器以ACK和返回文本消息进行响应,然后是CR LF

SERVER RESPONSE
0.002383    192.168.0.197   192.168.0.210   TCP 60  22223 → 61517 [ACK] Seq=1 Ack=19 Win=525568 Len=0
0.004112    192.168.0.197   192.168.0.210   TCP 66  22223 → 61517 [PSH, ACK] Seq=1 Ack=19 Win=525568 Len=12
0.004113    192.168.0.197   192.168.0.210   TCP 60  22223 → 61517 [FIN, PSH, ACK] Seq=13 Ack=19 Win=525568 Len=2

当我试图模拟客户端时,除了我没有得到一个[FIN,PSH,ACK],只有一个[PSH,ACK',服务器没有响应之外,一切似乎都一样。在我的实验中,我发现如果我在写入服务器后关闭流,我可以在wireshark上看到响应是发送的(但现在链接关闭了,所以我无法获得它(有人知道如何在保持连接有效的情况下生成[FIN,PSH,ACK]吗??

我的发送消息例程

Public Async Sub SendMessage(ByVal msg As String) 'Handles sendButton.Click
Try
If client IsNot Nothing AndAlso client.Connected Then
Dim stream As NetworkStream = client.GetStream
Dim myBytes2() As Byte = Encoding.Default.GetBytes(msg)
Try
Await stream.WriteAsync(myBytes2, 0, myBytes2.Length)
'stream.Close()
Catch ioex As System.IO.IOException
DisplayLog("Server terminated connection")
Catch odex As ObjectDisposedException
DisplayLog("client terminated connection")
Catch er As Exception
DisplayLog("ERROR Module:{" & GetModuleName(er) & "}" & Information.Err().Number & " Mess:" & er.Message)
End Try
End If
Catch er As Exception
DisplayLog("ERROR Module:{" & GetModuleName(er) & "}" & Information.Err().Number & " Mess:" & er.Message)
End Try

End Sub

我认为您对TCP的工作方式抱有错误的期望。FIN不是某条消息的结束,而是整个连接的结束。因此,它是在关闭流时发送的,但不是在消息之后发送的。

TCP根本不提供任何类型的消息语义,它只是一个字节流。如果您需要消息语义,您不能通过在现有连接中任意多次发送FIN来将这些消息语义添加到TCP,但您必须按流在TCP之上添加这些消息语义。典型的方法是在消息前面加上一个长度,或者有某种消息结束标记(比如基于文本的协议中的CR-LF(。

最新更新