Socket question.

When I close a socket in the server side, I found the client will receive some empty data automatically, even though I haven't sent anything in my code. I also found that some empty data will also be sent to the server automatically if I close a client side socket. These two cases could be reasonable since there may be some acknowledgement to be sent arround.

Upon closing a server side socket by calling its Close(), it's wired to see that ReceiveDataFromClientCallBack() will be called id the socket is a work socket. And the AcceptClientCallBack() will be also be called if the socket is a listner socket.

Anybody can explain this


Answer this question

Socket question.

  • colelaus

    The Connected, and Active flags may still be true even though the socket has already been closed.  They signify the state of the socket during the last IO, if there has been no attempt at IO since the socket closed they will still be true.

    You can write a bit to the socket when you get a zero result from EndReceive() to update these flags; but the other end has to know how to handle it in case they are truely connected.


  • Nikolay Shustov

    So far,
    I test the data received to be zero to know whether the sending socket has been closed or not,
    and use Connected==True or some other flags to test whether the socket closing is still accessible or not, so that the EndReceive() will be called/conditioned out.

    Thank you.

  • Morri1234

    Thank you very much for your reply. My question is too simple since I posted in sleepy state in deep night. Sorry about that.

    Observations: (only one client and one server in test)
    According to the following code snippet.
    1. When I call StopServer(), at the statement of ServerSocket.Close(); AcceptClientCallBack() will sometimes be invoked.
    2. When I close a WorkerSocket by calling
    WorkerSocket.Shutdown();WorkerSocket.Close(); The Client's ReceiveDataFromServerCallBack() will be invoked, and the data received is just empty.
    Then, Server's
    ReceiveDataFormClientCallback()
    will be invoked, the data received is also empty.
    3. When I close the ClientSocket, the WorkerSocket will also receive some empty data, just like 2.
    4. These empty data is not sent by my code.

    Question:
    1. Whenever a socket is closed, is there any automatic acknowledge between the peer sockets If it is, how to differentiate these acknowledgement from the normal data received

    2. Most wierd, AcceptClientCallBack()
    get called when closing the ServerSocket. Is there anything wrong with my code because of multi-threading

    A skelton of my code can be simplified as follows:
    ==========================================================
    Client:

    StartClient()//API
    {
       ClientSocket.BeginConnect();
       ClientSocket.BeginReceive(new AsyncCallback(ReceiveDataFromServerCallBack));
    }

    StopClient()//API
    {
       ClientSocket.ShutDown(SocketShutdown.Both);
       ClientSocket.Close();
    }

    ReceiveDataFromServerCallBack()
    {
       try 
       { 
          ClientSocket.EndReceive();
          ...
       }
       catch(Exceptione ex)
       {
          ClientSocket.ShutDown(SocketShutdown.Both);
          ClientSocket.Close();
       }
    }

    Server:
    StartServer()//API
    {
       ServerSocket.Bind();
       ServerSocket.Listen();
       ServerSocket.BeginAccept(new AsyncCallback(AcceptClientCallBack), ServerSocket);
    }

    StopServer()//API
    {
        //shut down all worker sockets
        //shut down the listener socket
        ServerSocket.ShutDown(SocketShutdown.Both);
        ServerSocket.Close();
    }

    AcceptClientCallBack()
    {
       try
       {
          Socket ServerSocket=AsyncOperationObj.AsyncState;
          Socket WorkerSocket=ServerSocket.EndAccept();
          ServerSocket.BeginAccept(new AsyncCallback(AcceptClientCallBack), ServerSocket);

          WorkerSocket.BeginReceive(new AsyncCallback(ReceiveDataFormClientCallback), WorkerSocket)
       }
       catch(Exceptione ex)
       {
          StopServer();
       }
    }

    ReceiveDataFormClientCallback()
    {
       try
       {
          Socket WorkerSocket=AsyncOperationObj.AsyncState;
          WorkerSocket.EndReceive();
       }
       catch(Exception ex)
       {
          WorkerSocket.ShutDown(SocketShutdown.Both);
          WorkerSocket.Close();
       }
    }
    =================================================================

    Thank you very much.



  • ciberch

    What do you need explained   You'll have to give us more to go one.  How do ReceiveDataFromClientCallBack() and AcceptClientCallBack() relate to the Socket class

    Also, what do you mean by empty data is sent automatically upon close   Random data is neither sent nor received.  If you're monitoring network traffic you'll see protocol data moving back and forth; but, that's transparent to the client and the server code.

  • Shane Stevens

    Your receive callback will be called immediatly when the server socket is ShutDown.  The Sockets's EndReceive() will return 0 signfying nothing was read and the socket has been shut down.

    See the Remarks section of NetworkStream.EndRead() documentation @ http://msdn.microsoft.com/library/default.asp url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclassendreceivetopic.asp

    If you don't check for 0 bytes read you'll eat up the CPU if calling BeginReceive() again becuase it will immediately call the callback with 0 bytes again.

    The same occurs with NetworkStream.EndRead(), if you're interested in network streams.



  • Socket question.