Async TCP System.Net.Socket send (Begin/End Send) not actually sending anything

拟墨画扇 提交于 2019-12-21 05:48:52

问题


Background:

I am running a TCP server on one machine with multiple clients on separate machines connecting over TCP, and I am monitoring network traffic with Wireshark, as well as with logging from within my server application, and through the System.Diagnostics tracelistener on System.Net.Sockets in verbose mode.

Problem:

Prompted to examine my logs due to some unexpected disconnects, I see some very strange behavior. According to the server application logs, and the System.Diagnostic output logs, my server is sending a 4 byte packet to a client using begin/end send. The BeginSend completes, and the EndSend also completes saying that it successfully sent the 4 byte packet.

However, when I look at the Wireshark logs, that packet never shows up. I am running Wireshark on the server machine, so there should be no reason for the packet to show up in my server and trace logs, but not in the Wireshark logs on the same machine.

Also, there is an unexpected disconnect that occurs soon after the supposedly successful packet send (~30 seconds later), which is caused by a SocketException on my server's EndReceive method. But during the time between the attempted send from the server, the server is acknowledging packets received from the client, so I know the connection is still active.

Has anyone out there had a similar experience, or know of a bug or something that might be causing this?

I would hate to think that this is occurring at the socket level, where TCP is saying that my packet is sent when it never even made it onto the wire, which would mean that I cannot rely on TCP as a reliable transport (which of course is the whole point of TCP).

Log Samples

From my server application:

    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)

From the System.Diagnostics trace log:

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

I would paste the Wireshark logs, too, but essentially there is nothing registering on the interface for that device at that time, except for the packets coming from the client, and the corresponding acknowledgments from the server.

Edit: As requested, here is the code for the send (shortened for space, and other reasons). Pretty simple, not much in the way of anything that could go wrong.

In my BeginSend method:

socket.BeginSend(data, 0, data.Length, SocketFlags.None, EndSend, state);

In my EndSend method:

bytesSent = socket.EndSend(ar);

Note: This is not my first rodeo, as they say... I have been writing servers and clients using TCP sockets for the last 15 years, and have never experienced this before.

Also, the version of .NET that I am using is 4.0... if that is of any relevance.

Help!


回答1:


One issue I've encountered with socket programming in .NET was related to garbage collection. My code was creating a socket and assigning to a local variable in my method instead of assigning to a member variable. The socket was then garbage-collected, causing a SocketException. Apparently, doing a BeginSend wasn't enough to hold a reference to that socket.

Moving the socket to a member variable solved the issue for me. Hopefully this is relevant to the issue you're encountering.




回答2:


I would hate to think that this is occurring at the socket level, where TCP is saying that my packet is sent when it never even made it onto the wire, which would mean that I cannot rely on TCP as a reliable transport (which of course is the whole point of TCP).

This statement is incorrect. Just because you successfully write to a socket does not mean that data was received by the client or even left your machine. It just means it was successfully written to the internal TCP/IP buffers. TCP/IP will send that data in as many or as few blocks/frames as it deems fit. This is especailly true if the data you are sending is small, TCP/IP will delay to try to aggregate additional data into the frame.

If you are not seeing it in Wireshark, then you are likely not listening on the right interface, have a filter set, or a firewall of some sort is preventing you from sending the data. Take a look at any antivirous or other layere service providers in place to see who could be getting in there.




回答3:


If it's possible to disregard its limitations, would it be possible for you to rewrite the application to use TcpClient instead of Socket? If your app is bound to TCP/IP anyway, at least for this particular socket, you might as well use the abstraction -- it might help. Also, you could try to use the EndSend(IAsyncResult, SocketError) overload to see if the SocketError object contains anything useful.

If none of these software tweaks helps, I have to agree that the problem must be below the .NET software level, i.e. in firewall software (or hardware), antivirus, etc.




回答4:


Well this question was ages ago, so you've probably moved on... in case someone else has the same problem, you may want to check whether Windows' Memory Pressure Protection might be kicking in. This will cause packets to be dropped when there are multiple simultaneous connections, which is what you're seeing.

Another experiment you can try is to temporarily turn off the firewall on your server machine. This will also turn off all of these protection mechanisms (if I'm not mistaken) and if things work then, you know that one of those is the culprit.



来源:https://stackoverflow.com/questions/7339103/async-tcp-system-net-socket-send-begin-end-send-not-actually-sending-anything

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!