class Server { static void Main(string[] args) { // create the listener socket IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); Socket serverSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 52000); serverSocket.Bind(ipEndPoint); serverSocket.Listen(100); AutoResetEvent connectedSignal = new AutoResetEvent(false); // establish connections with clients while (true) { serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), new Tuple<Socket, AutoResetEvent>(serverSocket, connectedSignal)); // wait here until we've established a connection connectedSignal.WaitOne(); } } // asynchronous callback to accept a connection static void AcceptCallback(IAsyncResult acceptAsynchResult) { var connectionObject = (Tuple<Socket, AutoResetEvent>)acceptAsynchResult.AsyncState; // signal to the loop in Main that we've established a connection connectionObject.Item2.Set(); Socket receiveSocket = connectionObject.Item1.EndAccept(acceptAsynchResult); // receive the data var readData = new Tuple<Socket, byte[]>(receiveSocket, new byte[1024]); receiveSocket.BeginReceive(readData.Item2, 0, readData.Item2.Length, SocketFlags.None, new AsyncCallback(ReadCallback), readData); } // asynchronous callback to read socket data static void ReadCallback(IAsyncResult readAsyncResult) { var readData = (Tuple<Socket, byte[]>)readAsyncResult.AsyncState; // handle SocketException where SocketErrorCode == SocketError.ConnectionReset // to gracefully handle sudden client disconnects int read = readData.Item1.EndReceive(readAsyncResult); if (read > 0) { // write received data to the console Console.WriteLine(Encoding.UTF8.GetString(readData.Item2, 0, read)); // set up to receive more data readData.Item1.BeginReceive(readData.Item2, 0, readData.Item2.Length, SocketFlags.None, new AsyncCallback(ReadCallback), readData); } } }
The server will establish connections as often as their are clients. An AutoResetEvent is used to signal when the server has established a connection with a client and should ready itself for another connection. The client:
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 52000); clientSocket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); clientSocket.Connect(ipe); clientSocket.Send(Encoding.UTF8.GetBytes("Hello World")); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Disconnect(false);