Socket Bugs on trying to send to disconnected clients

G

Guest

I just made a simple TCP server to experiment socket exception when I lost
the connection with my client.
In this test program I create a socket and wait for a client (a basic telnet
on another computer of my LAN) to connect. When the client is well connected,
I unplug the ethernet wire of the client and I wait for exception.
I thought that I will have an exception the next time I try to use the
socket to send or receive data. So I try to send data to the disconnected
client and the send call directly return to me that all bytes have been sent
!!!
Moreover, I check after the socket.Connected Boolean and it's True.
I find some clues on this article :
http://dam.mellis.org/2004/08/net_socket_bugs_gotchas/

This is my server code :

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text

Public Class Form1
Dim port As Integer = 10000

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim sckListening As Socket
Dim sckClient As Socket

sckListening = New Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp)
sckListening.Bind(New IPEndPoint(IPAddress.Any, port))
sckListening.Listen(5)
System.Console.WriteLine("Socket en écoute sur " &
sckListening.LocalEndPoint.ToString)
sckClient = sckListening.Accept()
System.Console.WriteLine("Serveur: Connexion acceptée avec " &
sckClient.RemoteEndPoint.ToString)

'I try tu use the SendTimeout param
sckClient.SendTimeout = 1000

'Here we sleep during 50 sec
'Between each sleep we check the socket.Connected var
Dim i As Integer
For i = 0 To 9
System.Console.WriteLine("Attente de plantage ... " & CStr((i +
1) * 5) & "sec")
System.Console.WriteLine("Socket connecté ? " &
sckClient.Connected.ToString)
Threading.Thread.Sleep(5000)
Next

'Here we try to send 6 bytes to the disconnected client
Dim nbByte As Integer
nbByte = sckClient.Send(Encoding.ASCII.GetBytes("hello!"), 6,
SocketFlags.None)
System.Console.WriteLine(CStr(nbByte))

'You don't have any exception yet
'I wait for exceptions maybe thrown due to the socket.sendtimeout
parameter
For i = 0 To 9
System.Console.WriteLine("Attente de plantage ... " & CStr((i +
1) * 5) & "sec")
System.Console.WriteLine("Socket connecté ? " &
sckClient.Connected.ToString)
Threading.Thread.Sleep(5000)
Next

'We finally made a success data send to a disconnected client without
any exception !!
System.Console.WriteLine("Fin")
End Sub
End Class

I search solutions to be able to detect client disconnection... Because the
..NET Framework appears to have some bugs in socket managing.

Thank You
 
L

Laura T.

It can take time to acknowledge that the socket connection is really broken.
It's not instant measure.

From the VS2005 documentation:
"
A successful completion of the Send method means that the underlying system
has had room to buffer your data for a network send.
..
..
..
The successful completion of a send does not indicate that the data was
successfully delivered.
"

I use this on our apps to check quite reliably that the socket is open on
both ends or not:

private static bool IsSocketReallyConnected(Socket socket)
{
bool retState = false;
bool blockingState = socket.Blocking;
try
{
byte[] tmp = new byte[1];

socket.Blocking = false;
socket.Send(tmp, 0, 0);
retState = true;
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK -> Buffer full for now
if (e.NativeErrorCode.Equals(10035))
{
retState = true;
}
}
finally
{
socket.Blocking = blockingState;
}

return retState;
}

And it's not a bug.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top