Home All Groups Group Topic Archive Search About

Socket Bugs on trying to send to disconnected clients

Author
20 Mar 2007 10:35 AM
Shackleton1986
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

Author
20 Mar 2007 11:52 AM
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.

Show quote
"Shackleton1986" <Shackleton1***@discussions.microsoft.com> ha scritto nel
messaggio news:18F90B9B-C5F3-441A-BFDF-31F589741153@microsoft.com...
>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

AddThis Social Bookmark Button