Socket Bugs on trying to send to disconnected clients

  • Thread starter Thread starter Guest
  • Start date Start date
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
 
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.
 
Back
Top