Socket.EndReceive question - in which scenarios does it return 0 (zero)?

Hi,
I have an application that works just fine. I am puzzled by the following issue though - in certain scenarios, Socket.EndReceive returns 0 bytes. According to the documentation, this happens when the remote host calls Socket.Shutdown or closes the Socket in another manner. Generally, I observe this to be correct .

However, there are several types of apps (remote hosts) for which this does not hold (the code is not mine so I cannot see what these apps are doing). Even though EndReceive returns 0 (zero) bytes, the remote host is still connected (Connected property of the Socket is true). Not only that, but if I call BeginReceive again, I will immediately be called back and when I call EndReceive I willagain receive zero bytes, etc.

Does anyone know what is it exactly that the remote app is doing to cause this behavior? I can work around the issue relatively easily, but it (unnecessarily?)complicates my code...

[952 byte] By [DrazenDotlic] at [2008-2-6]
# 1

Which version of the framework are you using? You were right. You should see this behavior only when the other end does a shutdown on send (atleast) or closes the socket. Even if the socket shutdown is called the socket.Connected will return true. Since you cannot see what the apps are doing, can you sniff the network using netmon or some other tool.

Malar at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 2

Thanks for your comments. The framework version is 1.1 (latest SP applied).

I will try to use a network sniffer, but the problem is that there are many remote machines connecting to me and it is not trivial to single out the "offending" ones (I have to closely watch the traces I have put in the code). Most of the remote host "behave", but a few don't.

Btw, do you know of a reliable way to detect that the remote host called shutdown (as you've pointed out, Connected property is still true in that context, thus out of the question).

Thanks in advance.

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 3

Hope you are aware of enabling tracing using config .. Make this xml file as <yourexename>.exe.config.. It will log into the file specified in the config... here it is System.Net.trace.log in the same dir as the exe.
<?xml version="1.0" encoding="UTF-8" ?>

<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="System.Net"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log"
/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
<add name="System.Net.Cache" value="Verbose" />
</switches>
</system.diagnostics>
</configuration>
>Btw, do you know of a reliable way to detect that the remote host called >shutdown (as you've pointed out, Connected property is still true in that context, >thus out of the question).

I dont know of any now. I'll get back to you on this soon..

Thanks

Malar at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 4
Malar wrote:

Hope you are aware of enabling tracing using config .. Make this xml file as <yourexename>.exe.config.. It will log into the file specified in the config... here it is System.Net.trace.log in the same dir as the exe.

I missed this somehow, thanks for the great tip. I will do further testing and see where it leads me. Btw, the docs do not say, but I seem to have similar problem with EndSend too - if that returns 0 (zero), should I assume the same thing (that the remote host disconnected)?

Thanks again.

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 5
Malar wrote:

Hope you are aware of enabling tracing using config
[snip]
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
[snip]


Are you sure that the <sources> element is available in 1.1? It's becoming clear now why I haven't heard about it - it's probably new for 2.0. I tried the configuration you suggested and it locks up the application...

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 6
Hi,
the tracing feature is new to 2.0. You have to use some network sniffing tools like Netmon
mahjayar at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 7
mahjayar wrote:
Hi,
the tracing feature is new to 2.0. You have to use some network sniffing tools like Netmon

OK, no problem. I found something that looks quite decent called Ethereal. Let's see what I can find tonight.

Any guesses why EndReceive returns zero and the socket still seems to be connected? Is this normal under certain circumstances?

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 8

Drazen Dotlic wrote:

OK, no problem. I found something that looks quite decent called Ethereal. Let's see what I can find tonight.

Any guesses why EndReceive returns zero and the socket still seems to be connected? Is this normal under certain circumstances?

Ethereal rocks! Not only are you able to sniff the network traffic, but the tool can analyze the traffic and parse raw data into many (almost 700) high-level protocols and show you the "aggregated" view on the data. But enough rambling on the Ethereal itself, here's what it showed: the clients that would case the described behavior were indeed closing the connection. So returning zero makes sense, but I don't know why the Connected property is still on. Actually, something funny is going on, have a look at the data exchange:
1. Me -> Remote SYN
2. Remote -> Me SYN, ACK
3. Me -> Remote ACK
4. Me -> Remote <some_data>
5. Remote -> Me FIN, ACK
6. Me -> Remote ACK
7. Remote -> Me RST, ACK
8. Me -> Remote RST

I am puzzled with steps 7 & 8 - if I understand TCP protocol, after step 6 the connection is gracefully closed. What's with 7 & 8? Could that be the reason that Connected property is still on?

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 9
TCP Graceful close involves:

1. (B) ACK/FIN --> (A)

2. (B) <-- ACK/FIN (A)

3. (B) ACK --> (A)

In addition, host A in step 2 is not required to send the FIN packet right away. It can continue to send data and send the FIN packet at some later time.

If either host needs to tear down the connection quickly (timeout etc.), a RST (Reset) packet is sent which quickly brings down the connection.

MikeFlasko at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 10
Mike Flasko wrote:
TCP Graceful close involves:

1. (B) ACK/FIN --> (A)

2. (B) <-- ACK/FIN (A)

3. (B) ACK --> (A)

In addition, host A in step 2 is not required to send the FIN packet right away. It can continue to send data and send the FIN packet at some later time.

If either host needs to tear down the connection quickly (timeout, host unreachable, etc.), a RST (Reset) packet is sent which quickly terminates both directions of a TCP connection. RST packets are not acknowledged.

Thanks for your comments. One other thing - I can see RST packets being acknowledged, but it is not a problem for me.

Anyway, the only thing that might confuse people is the fact that even though EndReceive returned 0, the Connected property is still true for a little while. However, the connection is going down, and one can rely on the EndReceive to return 0 in case of remote host closing the connection.

My other question turned out to be a bug on my side - EndSend returned zero because I was sending zero bytes ;)

I'd like to use this chance to commend the developers of the .NET Framework on the job well done - Socket programming has never been easier. Since I am "porting" my app to .NET 2.0 (beta2) in the next week or so, I can only expect even better things to come.

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 11
>Anyway, the only thing that might confuse people is the fact that even though >EndReceive returned 0, the Connected property is still true for a little while. >However, the connection is going down, and one can rely on the EndReceive to >return 0 in case of remote host closing the connection.
No this is not true. A remote socket shutdown(socketshutdown.send) would cause the endreceive to return 0. The socket cannot receive data anymore but can still continue sending data to the other end. endreceive 0 doesnt mean that the socket is disconnected
Malar at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 12
Malar wrote:
>Anyway, the only thing that might confuse people is the fact that even though >EndReceive returned 0, the Connected property is still true for a little while. >However, the connection is going down, and one can rely on the EndReceive to >return 0 in case of remote host closing the connection.
No this is not true. A remote socket shutdown(socketshutdown.send) would cause the endreceive to return 0. The socket cannot receive data anymore but can still continue sending data to the other end. endreceive 0 doesnt mean that the socket is disconnected

Cool, this is good to know. So the .NET FCL is right - the socket is indeed still connected at that time. In any case, knowing that the remote host called shutdown is good enough for me to treat the socket as "closed" in my scenario. Thanks for clarification.

DrazenDotlic at 2007-9-9 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...

.NET Development

Site Classified