6

I'm writing my first TCP server using Microsoft's supplied Async examples.

https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx

I have everything working from the example. I am extending it as a simple chat program. But I am having trouble following the steps of this program (probably because of its async nature). When a message is received, it echoes back to the client and closes the socket. I do not see where it goes back to re-open the socket.

public static void StartListening() {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.
        // The DNS name of the computer
        // running the listener is "host.contoso.com".
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp );

        // Bind the socket to the local endpoint and listen for incoming connections.
        try {
            listener.Bind(localEndPoint);
            listener.Listen(100);

            while (true) {
                // Set the event to nonsignaled state.
                allDone.Reset();

                // Start an asynchronous socket to listen for connections.
                Console.WriteLine("Waiting for a connection...");
                listener.BeginAccept( 
                    new AsyncCallback(AcceptCallback),
                    listener );

                // Wait until a connection is made before continuing.
                allDone.WaitOne();
            }

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

private static void SendCallback(IAsyncResult ar) {
        try {
            // Retrieve the socket from the state object.
            Socket handler = (Socket) ar.AsyncState;

            // Complete sending the data to the remote device.
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to client.", bytesSent);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }

Also, is it not normal to leave the socket open?

user3822370
  • 641
  • 7
  • 20

1 Answers1

2

When a message is received, it echoes back to the client and closes the socket. I do not see where it goes back to re-open the socket.

That is because it doesn't. The communication is done, the server receives, sends a reply and is done with that connection. It just continues to wait for new connections on the listening socket. You have a while (true). You'll keep waiting for new incoming connections in the accept call. You'll get a new socket for each new client.

Also, is it not normal to leave the socket open

Yes, the listening socket remains open. It is kept open to keep on receiving new connections using accept

A better way to write a echo server using async and await can be found here : Using .Net 4.5 Async Feature for Socket Programming

Community
  • 1
  • 1
Philip Stuyck
  • 7,344
  • 3
  • 28
  • 39
  • So the socket is still open, but the connection to that client is closed? I supposed my actual question should have been, `is it normal to leave the connection to the client open`, not the socket. – user3822370 Aug 08 '15 at 16:56
  • 1
    You have it all wrong. A listening socket is in listening state and is never used in a real connection. Whenever there is an incoming connection, what will happen is that the listening socket is cloned into a new socket, but this is a servicing socket that belongs to a socket pair containing this servicing socket and the connection socket. The socket pair identifies the connection. A listening socket is never part of a socket pair and hence there is no connection it belongs to. It is only used as a way to establish a connection. – Philip Stuyck Aug 08 '15 at 17:12
  • 1
    See also my answer here http://stackoverflow.com/questions/30054673/tcp-listener-and-client-listening-to-specfic-ip/30060384#30060384. Please mark as usefull or answer if this helps you. – Philip Stuyck Aug 08 '15 at 17:18
  • Okay, your linked post does help a lot. So I'll try one more time! Is it normal to leave the service socket open ? :) – user3822370 Aug 08 '15 at 17:23
  • 1
    The servicing socket is closed in your sample code : handler.Shutdown(SocketShutdown.Both); handler.Close(); Webservers that have a clear request reply mechanism will close the connection. Same for echoservers, timeofday. But a chat system will typically leave the sockets open for a longer time, depending on their implementation of course. – Philip Stuyck Aug 08 '15 at 17:26
  • That is what I thought. Thank you. – user3822370 Aug 08 '15 at 17:28