See Also: Socket Members
The System.Net.Sockets.Socket class provides a rich set of methods and properties for network communications. The System.Net.Sockets.Socket class allows you to perform both synchronous and asynchronous data transfer using any of the communication protocols listed in the System.Net.Sockets.ProtocolType enumeration.
The System.Net.Sockets.Socket class follows the .NET Framework naming pattern for asynchronous methods. For example, the synchronous Socket.Receive(Byte[], int, SocketFlags) method corresponds to the asynchronous Socket.BeginReceive(Byte[], int, int, SocketFlags, AsyncCallback, object) and Socket.EndReceive(IAsyncResult) methods.
If your application only requires one thread during execution, use the following methods, which are designed for synchronous operation mode.
If you are using a connection-oriented protocol such as TCP, your server can listen for connections using the Socket.Listen(int) method. The Socket.Accept method processes any incoming connection requests and returns a System.Net.Sockets.Socket that you can use to communicate data with the remote host. Use this returned System.Net.Sockets.Socket to call the Socket.Send(Byte[], int, SocketFlags) or Socket.Receive(Byte[], int, SocketFlags) method. Call the Socket.Bind(System.Net.EndPoint) method prior to calling the Socket.Listen(int) method if you want to specify the local IP address and port number. Use a port number of zero if you want the underlying service provider to assign a free port for you. If you want to connect to a listening host, call the Socket.Connect(System.Net.EndPoint) method. To communicate data, call the Socket.Send(Byte[], int, SocketFlags) or Socket.Receive(Byte[], int, SocketFlags) method.
If you are using a connectionless protocol such as UDP, you do not need to listen for connections at all. Call the Socket.ReceiveFrom(Byte[], int, int, SocketFlags, System.Net.EndPoint@) method to accept any incoming datagrams. Use the Socket.SendTo(Byte[], int, int, SocketFlags, System.Net.EndPoint) method to send datagrams to a remote host.
To process communications using separate threads during execution, use the following methods, which are designed for asynchronous operation mode.
If you are using a connection-oriented protocol such as TCP, use the System.Net.Sockets.Socket, Socket.BeginConnect(System.Net.EndPoint, AsyncCallback, object), and Socket.EndConnect(IAsyncResult) methods to connect with a listening host. Use the Socket.BeginSend(Byte[], int, int, SocketFlags, AsyncCallback, object) and Socket.EndSend(IAsyncResult) or Socket.BeginReceive(Byte[], int, int, SocketFlags, AsyncCallback, object) and Socket.EndReceive(IAsyncResult) methods to communicate data asynchronously. Incoming connection requests can be processed using Socket.BeginAccept(AsyncCallback, object) and Socket.EndAccept(IAsyncResult).
If you are using a connectionless protocol such as UDP, you can use Socket.BeginSendTo(Byte[], int, int, SocketFlags, System.Net.EndPoint, AsyncCallback, object) and Socket.EndSendTo(IAsyncResult) to send datagrams, and Socket.BeginReceiveFrom(Byte[], int, int, SocketFlags, System.Net.EndPoint@, AsyncCallback, object) and Socket.EndReceiveFrom(IAsyncResult, System.Net.EndPoint@) to receive datagrams.
If you perform multiple asynchronous operations on a socket, they do not necessarily complete in the order in which they are started.
When you are finished sending and receiving data, use the Socket.Shutdown(SocketShutdown) method to disable the System.Net.Sockets.Socket. After calling Socket.Shutdown(SocketShutdown), call the Socket.Close method to release all resources associated with the System.Net.Sockets.Socket.
The System.Net.Sockets.Socket class allows you to configure your System.Net.Sockets.Socket using the Socket.SetSocketOption(SocketOptionLevel, SocketOptionName, int) method. Retrieve these settings using the Socket.GetSocketOption(SocketOptionLevel, SocketOptionName) method.
If you are writing a relatively simple application and do not require maximum performance, consider using System.Net.Sockets.TcpClient, System.Net.Sockets.TcpListener, and System.Net.Sockets.UdpClient. These classes provide a simpler and more user-friendly interface to System.Net.Sockets.Socket communications.
The following examples provide a client/server application that demonstrates the use of asynchronous communication between sockets. Run the client and server on different consoles.
The following code is for the server application. Start this application before the client application.
C# Example
using System; using System.Threading; using System.Text; using System.Net; using System.Net.Sockets; public class Server { // used to pass state information to delegate internal class StateObject { internal byte[] sBuffer; internal Socket sSocket; internal StateObject(int size, Socket sock) { sBuffer = new byte[size]; sSocket = sock; } } static void Main() { IPAddress ipAddress = Dns.Resolve( Dns.GetHostName() ).AddressList[0]; IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 1800); Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(ipEndpoint); listenSocket.Listen(1); IAsyncResult asyncAccept = listenSocket.BeginAccept( new AsyncCallback(Server.acceptCallback), listenSocket ); // could call listenSocket.EndAccept(asyncAccept) here // instead of in the callback method, but since // EndAccept blocks, the behavior would be similar to // calling the synchronous Accept method Console.Write("Connection in progress."); if( writeDot(asyncAccept) == true ) { // allow time for callbacks to // finish before the program ends Thread.Sleep(3000); } } public static void acceptCallback(IAsyncResult asyncAccept) { Socket listenSocket = (Socket)asyncAccept.AsyncState; Socket serverSocket = listenSocket.EndAccept(asyncAccept); // arriving here means the operation completed // (asyncAccept.IsCompleted = true) but not // necessarily successfully if( serverSocket.Connected == false ) { Console.WriteLine( ".server is not connected." ); return; } else Console.WriteLine( ".server is connected." ); listenSocket.Close(); StateObject stateObject = new StateObject(16, serverSocket); // this call passes the StateObject because it // needs to pass the buffer as well as the socket IAsyncResult asyncReceive = serverSocket.BeginReceive( stateObject.sBuffer, 0, stateObject.sBuffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), stateObject); Console.Write("Receiving data."); writeDot(asyncReceive); } public static void receiveCallback(IAsyncResult asyncReceive) { StateObject stateObject = (StateObject)asyncReceive.AsyncState; int bytesReceived = stateObject.sSocket.EndReceive(asyncReceive); Console.WriteLine( ".{0} bytes received: {1}", bytesReceived.ToString(), Encoding.ASCII.GetString(stateObject.sBuffer) ); byte[] sendBuffer = Encoding.ASCII.GetBytes("Goodbye"); IAsyncResult asyncSend = stateObject.sSocket.BeginSend( sendBuffer, 0, sendBuffer.Length, SocketFlags.None, new AsyncCallback(sendCallback), stateObject.sSocket); Console.Write("Sending response."); writeDot(asyncSend); } public static void sendCallback(IAsyncResult asyncSend) { Socket serverSocket = (Socket)asyncSend.AsyncState; int bytesSent = serverSocket.EndSend(asyncSend); Console.WriteLine( ".{0} bytes sent.{1}{1}Shutting down.", bytesSent.ToString(), Environment.NewLine ); serverSocket.Shutdown(SocketShutdown.Both); serverSocket.Close(); } // times out after 20 seconds but operation continues internal static bool writeDot(IAsyncResult ar) { int i = 0; while( ar.IsCompleted == false ) { if( i++ > 40 ) { Console.WriteLine("Timed out."); return false; } Console.Write("."); Thread.Sleep(500); } return true; } }
The following code is for the client application. When starting the application, supply the hostname of the console running the server application as an input parameter (for example, ProgramName hostname ).
C# Example
using System; using System.Threading; using System.Text; using System.Net; using System.Net.Sockets; public class Client { // used to pass state information to delegate class StateObject { internal byte[] sBuffer; internal Socket sSocket; internal StateObject(int size, Socket sock) { sBuffer = new byte[size]; sSocket = sock; } } static void Main(string[] argHostName) { IPAddress ipAddress = Dns.Resolve( argHostName[0] ).AddressList[0]; IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 1800); Socket clientSocket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IAsyncResult asyncConnect = clientSocket.BeginConnect( ipEndpoint, new AsyncCallback(connectCallback), clientSocket ); Console.Write("Connection in progress."); if( writeDot(asyncConnect) == true ) { // allow time for callbacks to // finish before the program ends Thread.Sleep(3000); } } public static void connectCallback(IAsyncResult asyncConnect) { Socket clientSocket = (Socket)asyncConnect.AsyncState; clientSocket.EndConnect(asyncConnect); // arriving here means the operation completed // (asyncConnect.IsCompleted = true) but not // necessarily successfully if( clientSocket.Connected == false ) { Console.WriteLine( ".client is not connected." ); return; } else Console.WriteLine( ".client is connected." ); byte[] sendBuffer = Encoding.ASCII.GetBytes("Hello"); IAsyncResult asyncSend = clientSocket.BeginSend( sendBuffer, 0, sendBuffer.Length, SocketFlags.None, new AsyncCallback(sendCallback), clientSocket); Console.Write("Sending data."); writeDot(asyncSend); } public static void sendCallback(IAsyncResult asyncSend) { Socket clientSocket = (Socket)asyncSend.AsyncState; int bytesSent = clientSocket.EndSend(asyncSend); Console.WriteLine( ".{0} bytes sent.", bytesSent.ToString() ); StateObject stateObject = new StateObject(16, clientSocket); // this call passes the StateObject because it // needs to pass the buffer as well as the socket IAsyncResult asyncReceive = clientSocket.BeginReceive( stateObject.sBuffer, 0, stateObject.sBuffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), stateObject); Console.Write("Receiving response."); writeDot(asyncReceive); } public static void receiveCallback(IAsyncResult asyncReceive) { StateObject stateObject = (StateObject)asyncReceive.AsyncState; int bytesReceived = stateObject.sSocket.EndReceive(asyncReceive); Console.WriteLine( ".{0} bytes received: {1}{2}{2}Shutting down.", bytesReceived.ToString(), Encoding.ASCII.GetString(stateObject.sBuffer), Environment.NewLine ); stateObject.sSocket.Shutdown(SocketShutdown.Both); stateObject.sSocket.Close(); } // times out after 2 seconds but operation continues internal static bool writeDot(IAsyncResult ar) { int i = 0; while( ar.IsCompleted == false ) { if( i++ > 20 ) { Console.WriteLine("Timed out."); return false; } Console.Write("."); Thread.Sleep(100); } return true; } }
The output of the server application is
Connection in progress...........server is connected.The output of the client application is
Connection in progress......client is connected.