【发布时间】:2011-09-07 18:58:37
【问题描述】:
背景:
我在一台机器上运行 TCP 服务器,多个客户端在通过 TCP 连接的不同机器上,我正在使用 Wireshark 监控网络流量,以及从我的服务器应用程序中进行日志记录,并通过 System.Diagnostics 跟踪侦听器System.Net.Sockets 处于详细模式。
问题:
由于一些意外断开连接提示检查我的日志,我看到一些非常奇怪的行为。根据服务器应用程序日志和 System.Diagnostic 输出日志,我的服务器正在使用开始/结束发送向客户端发送一个 4 字节数据包。 BeginSend 完成,EndSend 也完成,表示它成功发送了 4 字节数据包。
但是,当我查看 Wireshark 日志时,该数据包从未出现过。我在服务器机器上运行 Wireshark,所以数据包应该没有理由出现在我的服务器和跟踪日志中,但不会出现在同一台机器上的 Wireshark 日志中。
此外,在所谓的成功发送数据包后不久(约 30 秒后)发生意外断开连接,这是由我的服务器的 EndReceive 方法上的 SocketException 引起的。但是在尝试从服务器发送之间的时间段内,服务器正在确认从客户端接收到的数据包,所以我知道连接仍然处于活动状态。
有没有人有类似的经历,或者知道一个错误或可能导致这种情况的东西?
我不想认为这是在套接字级别发生的,TCP 说我的数据包在它甚至从未到达网络时发送,这意味着我不能依赖 TCP 作为可靠的传输(这当然是 TCP 的重点)。
日志样本
来自我的服务器应用程序:
2011-09-07 10:41:38,812 Attempting to send Packet (BeginSend - 4 bytes)
2011-09-07 10:41:38,812 Sent Packet (EndSend - 4 bytes)
来自 System.Diagnostics 跟踪日志:
System.Net.Sockets Verbose: 0 : [4376] Socket#19699911::BeginSend()
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [0980] Data from Socket#19699911::PostCompletion
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [0980] 00000000 : 02 04 00 00 : ....
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [4376] Socket#19699911::EndSend(OverlappedAsyncResult#44209720)
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [4376] Exiting Socket#19699911::EndSend() -> 4#4
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [4376] Exiting Socket#19699911::BeginSend() -> OverlappedAsyncResult#44209720
DateTime=2011-09-07T17:41:38.8125000Z
我也会粘贴 Wireshark 日志,但当时该设备的接口上基本上没有任何注册,除了来自客户端的数据包和来自服务器的相应确认。
编辑: 根据要求,这是发送的代码(由于空间和其他原因而缩短)。很简单,没有太多可能出错的地方。
在我的 BeginSend 方法中:
socket.BeginSend(data, 0, data.Length, SocketFlags.None, EndSend, state);
在我的 EndSend 方法中:
bytesSent = socket.EndSend(ar);
注意:正如他们所说,这不是我第一次参加牛仔竞技表演...过去 15 年来我一直在使用 TCP 套接字编写服务器和客户端,以前从未经历过。
另外,我使用的 .NET 版本是 4.0...如果有任何相关性的话。
救命!
【问题讨论】:
-
您可以在帖子中添加相关的客户端和服务器代码吗?可能代码有错误。
-
添加了一些代码...但实际上并没有什么特别的。这是一个简单的 BeginSend 和 EndSend...您可以从 MSDN 或其他地方获取任何示例代码并重现我所看到的。
-
也许我对 TCP 如何在 .NET 平台上工作的理解不正确......当消息已传输到接收方并得到接收方确认后,Socket.EndSend 调用是否会成功返回?或者当 .NET 将消息成功发送到网络接口时,EndSend 是否会成功?如果是后者,网络适配器故障可能会解释我所看到的情况。
-
客户端看到那个 4 字节的传输了吗?您的帖子暗示客户端和服务器之间的对话无论如何都会继续进行。
-
另外,
SocketException提供了哪些详细信息?信息? Error code?
标签: c# sockets diagnostics