달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2017. 3. 2. 03:17

Sockets 프로그래밍/C#2017. 3. 2. 03:17


  1. Sockets
  2. SocketAsyncEventArgs Class
  3. TcpListener Class
  4. TcpClient Class





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


Sockets


The System.Net.Sockets namespace contains a managed implementation of the Windows Sockets interface. All other network-access classes in the System.Net namespace are built on top of this implementation of sockets.

The .NET Framework Socket class is a managed-code version of the socket services provided by the Winsock32 API. In most cases, the Socket class methods simply marshal data into their native Win32 counterparts and handle any necessary security checks.

The Socket class supports two basic modes, synchronous and asynchronous. In synchronous mode, calls to functions that perform network operations (such as Send and Receive) wait until the operation completes before returning control to the calling program. In asynchronous mode, these calls return immediately.






How to: Create a Socket


Before you can use a socket to communicate with remote devices, the socket must be initialized with protocol and network address information. The constructor for the Socket class has parameters that specify the address family, socket type, and protocol type that the socket uses to make connections.

The following example creates a Socket that can be used to communicate on a TCP/IP-based network, such as the Internet.

Socket s = new Socket(AddressFamily.InterNetwork,   
   SocketType.Stream, ProtocolType.Tcp);  

To use UDP instead of TCP, change the protocol type, as in the following example:

Socket s = new Socket(AddressFamily.InterNetwork,   
   SocketType.Dgram, ProtocolType.Udp);  

The AddressFamily enumeration specifies the standard address families used by the Socket class to resolve network addresses (for example, the AddressFamily.InterNetwork member specifies the IP version 4 address family).

The SocketType enumeration specifies the type of socket (for example, the SocketType.Stream member indicates a standard socket for sending and receiving data with flow control).

The ProtocolType enumeration specifies the network protocol to use when communicating on the Socket (for example, ProtocolType.Tcp indicates that the socket uses TCP; ProtocolType.Udp indicates that the socket uses UDP).

After a Socket is created, it can either initiate a connection to a remote endpoint or receive connections from remote devices.





Using Client Sockets


Before you can initiate a conversation through a Socket, you must create a data pipe between your application and the remote device. Although other network address families and protocols exist, this example shows how to create a TCP/IP connection to a remote service.

TCP/IP uses a network address and a service port number to uniquely identify a service. The network address identifies a specific device on the network; the port number identifies the specific service on that device to connect to. The combination of network address and service port is called an endpoint, which is represented in the .NET Framework by the EndPoint class. A descendant of EndPoint is defined for each supported address family; for the IP address family, the class is IPEndPoint.

The Dns class provides domain-name services to applications that use TCP/IP Internet services. The Resolve method queries a DNS server to map a user-friendly domain name (such as "host.contoso.com") to a numeric Internet address (such as 192.168.1.1). Resolve returns an IPHostEnty that contains a list of addresses and aliases for the requested name. In most cases, you can use the first address returned in the AddressList array. The following code gets an IPAddress containing the IP address for the server host.contoso.com.

IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");  
IPAddress ipAddress = ipHostInfo.AddressList[0];  

The Internet Assigned Numbers Authority (Iana) defines port numbers for common services (for more information, see www.iana.org/assignments/port-numbers). Other services can have registered port numbers in the range 1,024 to 65,535. The following code combines the IP address for host.contoso.com with a port number to create a remote endpoint for a connection.

IPEndPoint ipe = new IPEndPoint(ipAddress,11000);  

After determining the address of the remote device and choosing a port to use for the connection, the application can attempt to establish a connection with the remote device. The following example uses an existing IPEndPoint to connect to a remote device and catches any exceptions that are thrown.

try {  
    s.Connect(ipe);  
} catch(ArgumentNullException ae) {  
    Console.WriteLine("ArgumentNullException : {0}", ae.ToString());  
} catch(SocketException se) {  
    Console.WriteLine("SocketException : {0}", se.ToString());  
} catch(Exception e) {  
    Console.WriteLine("Unexpected exception : {0}", e.ToString());  
}






Using a Synchronous Client Socket


A synchronous client socket suspends the application program while the network operation completes. Synchronous sockets are not suitable for applications that make heavy use of the network for their operation, but they can enable simple access to network services for other applications.

To send data, pass a byte array to one of the Socket class's send-data methods (Send and SendTo). The following example encodes a string into a byte array buffer using the Encoding.ASCII property and then transmits the buffer to the network device using the Send method. The Send method returns the number of bytes sent to the network device.

byte[] msg = System.Text.Encoding.ASCII.GetBytes("This is a test");  
int bytesSent = s.Send(msg);  

The Send method removes the bytes from the buffer and queues them with the network interface to be sent to the network device. The network interface might not send the data immediately, but it will send it eventually, as long as the connection is closed normally with the Shutdown method.

To receive data from a network device, pass a buffer to one of the Socket class's receive-data methods (Receive and ReceiveFrom). Synchronous sockets will suspend the application until bytes are received from the network or until the socket is closed. The following example receives data from the network and then displays it on the console. The example assumes that the data coming from the network is ASCII-encoded text. The Receive method returns the number of bytes received from the network.

byte[] bytes = new byte[1024];  
int bytesRec = s.Receive(bytes);  
Console.WriteLine("Echoed text = {0}",  
    System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRec));  

When the socket is no longer needed, you need to release it by calling the Shutdown method and then calling the Close method. The following example releases a Socket. The SocketShutdown enumeration defines constants that indicate whether the socket should be closed for sending, for receiving, or for both.

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






Using an Asynchronous Client Socket


An asynchronous client socket does not suspend the application while waiting for network operations to complete. Instead, it uses the standard .NET Framework asynchronous programming model to process the network connection on one thread while the application continues to run on the original thread. Asynchronous sockets are appropriate for applications that make heavy use of the network or that cannot wait for network operations to complete before continuing.

The Socket class follows the .NET Framework naming pattern for asynchronous methods; for example, the synchronous Receive method corresponds to the asynchronous BeginReceive and EndReceive methods.

Asynchronous operations require a callback method to return the result of the operation. If your application does not need to know the result, then no callback method is required. The example code in this section demonstrates using a method to start connecting to a network device and a callback method to complete the connection, a method to start sending data and a callback method to complete the send, and a method to start receiving data and a callback method to end receiving data.

Asynchronous sockets use multiple threads from the system thread pool to process network connections. One thread is responsible for initiating the sending or receiving of data; other threads complete the connection to the network device and send or receive the data. In the following examples, instances of the System.Threading.ManualResetEvent class are used to suspend execution of the main thread and signal when execution can continue.

In the following example, to connect an asynchronous socket to a network device, the Connect method initializes a Socket and then calls the BeginConnect method, passing a remote endpoint that represents the network device, the connect callback method, and a state object (the client Socket), which is used to pass state information between asynchronous calls. The example implements the Connect method to connect the specified Socket to the specified endpoint. It assumes a global ManualResetEvent named connectDone.

public static void Connect(EndPoint remoteEP, Socket client) {  
    client.BeginConnect(remoteEP,   
        new AsyncCallback(ConnectCallback), client );  
  
   connectDone.WaitOne();  
}  

The connect callback method ConnectCallback implements the AsyncCallback delegate. It connects to the remote device when the remote device is available and then signals the application thread that the connection is complete by setting the ManualResetEvent connectDone. The following code implements the ConnectCallback method.

private static void ConnectCallback(IAsyncResult ar) {  
    try {  
        // Retrieve the socket from the state object.  
        Socket client = (Socket) ar.AsyncState;  
  
        // Complete the connection.  
        client.EndConnect(ar);  
  
        Console.WriteLine("Socket connected to {0}",  
            client.RemoteEndPoint.ToString());  
  
        // Signal that the connection has been made.  
        connectDone.Set();  
    } catch (Exception e) {  
        Console.WriteLine(e.ToString());  
    }  
}  

The example method Send encodes the specified string data in ASCII format and sends it asynchronously to the network device represented by the specified socket. The following example implements the Send method.

private static void Send(Socket client, String data) {  
    // Convert the string data to byte data using ASCII encoding.  
    byte[] byteData = Encoding.ASCII.GetBytes(data);  
  
    // Begin sending the data to the remote device.  
    client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,  
        new AsyncCallback(SendCallback), client);  
}  

The send callback method SendCallback implements the AsyncCallback delegate. It sends the data when the network device is ready to receive. The following example shows the implementation of the SendCallback method. It assumes a global ManualResetEvent named sendDone.

private static void SendCallback(IAsyncResult ar) {  
    try {  
        // Retrieve the socket from the state object.  
        Socket client = (Socket) ar.AsyncState;  
  
        // Complete sending the data to the remote device.  
        int bytesSent = client.EndSend(ar);  
        Console.WriteLine("Sent {0} bytes to server.", bytesSent);  
  
        // Signal that all bytes have been sent.  
        sendDone.Set();  
    } catch (Exception e) {  
        Console.WriteLine(e.ToString());  
    }  
}  

Reading data from a client socket requires a state object that passes values between asynchronous calls. The following class is an example state object for receiving data from a client socket. It contains a field for the client socket, a buffer for the received data, and a StringBuilder to hold the incoming data string. Placing these fields in the state object allows their values to be preserved across multiple calls to read data from the client socket.

public class StateObject {  
    // Client socket.  
    public Socket workSocket = null;  
    // Size of receive buffer.  
    public const int BufferSize = 256;  
    // Receive buffer.  
    public byte[] buffer = new byte[BufferSize];  
    // Received data string.  
    public StringBuilder sb = new StringBuilder();  
}  

The example Receive method sets up the state object and then calls the BeginReceive method to read the data from the client socket asynchronously. The following example implements the Receive method.

private static void Receive(Socket client) {  
    try {  
        // Create the state object.  
        StateObject state = new StateObject();  
        state.workSocket = client;  
  
        // Begin receiving the data from the remote device.  
        client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,  
            new AsyncCallback(ReceiveCallback), state);  
    } catch (Exception e) {  
        Console.WriteLine(e.ToString());  
    }  
}  

The receive callback method ReceiveCallback implements the AsyncCallback delegate. It receives the data from the network device and builds a message string. It reads one or more bytes of data from the network into the data buffer and then calls the BeginReceive method again until the data sent by the client is complete. Once all the data is read from the client, ReceiveCallback signals the application thread that the data is complete by setting the ManualResetEvent sendDone.

The following example code implements the ReceiveCallback method. It assumes a global string named response that holds the received string and a global ManualResetEvent named receiveDone. The server must shut down the client socket gracefully to end the network session.

private static void ReceiveCallback( IAsyncResult ar ) {  
    try {  
        // Retrieve the state object and the client socket   
        // from the asynchronous state object.  
        StateObject state = (StateObject) ar.AsyncState;  
        Socket client = state.workSocket;  
        // Read data from the remote device.  
        int bytesRead = client.EndReceive(ar);  
        if (bytesRead > 0) {  
            // There might be more data, so store the data received so far.  
            state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));  
                //  Get the rest of the data.  
            client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,  
                new AsyncCallback(ReceiveCallback), state);  
        } else {  
            // All the data has arrived; put it in response.  
            if (state.sb.Length > 1) {  
                response = state.sb.ToString();  
            }  
            // Signal that all bytes have been received.  
            receiveDone.Set();  
        }  
    } catch (Exception e) {  
        Console.WriteLine(e.ToString());  
    }  
}






Listening with Sockets


Listener or server sockets open a port on the network and then wait for a client to connect to that port. Although other network address families and protocols exist, this example shows how to create remote service for a TCP/IP network.

The unique address of a TCP/IP service is defined by combining the IP address of the host with the port number of the service to create an endpoint for the service. The Dns class provides methods that return information about the network addresses supported by the local network device. When the local network device has more than one network address, or if the local system supports more than one network device, the Dns class returns information about all network addresses, and the application must choose the proper address for the service. The Internet Assigned Numbers Authority (Iana) defines port numbers for common services (for more information, see www.iana.org/assignments/port-numbers). Other services can have registered port numbers in the range 1,024 to 65,535.

The following example creates an IPEndPoint for a server by combining the first IP address returned by Dns for the host computer with a port number chosen from the registered port numbers range.

IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());  
IPAddress ipAddress = ipHostInfo.AddressList[0];  
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);  

After the local endpoint is determined, the Socket must be associated with that endpoint using the Bind method and set to listen on the endpoint using the Listen method. Bind throws an exception if the specific address and port combination is already in use. The following example demonstrates associating a Socket with an IPEndPoint.

listener.Bind(localEndPoint);  
listener.Listen(100);  

The Listen method takes a single parameter that specifies how many pending connections to the Socket are allowed before a server busy error is returned to the connecting client. In this case, up to 100 clients are placed in the connection queue before a server busy response is returned to client number 101.








Using a Synchronous Server Socket


Synchronous server sockets suspend the execution of the application until a connection request is received on the socket. Synchronous server sockets are not suitable for applications that make heavy use of the network in their operation, but they can be suitable for simple network applications.

After a Socket is set to listen on an endpoint using the Bind and Listen methods, it is ready to accept incoming connection requests using the Accept method. The application is suspended until a connection request is received when the Accept method is called.

When a connection request is received, Accept returns a new Socket instance that is associated with the connecting client. The following example reads data from the client, displays it on the console, and echoes the data back to the client. The Socket does not specify any messaging protocol, so the string "<EOF>" marks the end of the message data. It assumes that a Socket named listener has been initialized and bound to an endpoint.

Console.WriteLine("Waiting for a connection..."); Socket handler = listener.Accept(); String data = null; while (true) { bytes = new byte[1024]; int bytesRec = handler.Receive(bytes); data += Encoding.ASCII.GetString(bytes,0,bytesRec); if (data.IndexOf("<EOF>") > -1) { break; } } Console.WriteLine( "Text received : {0}", data); byte[] msg = Encoding.ASCII.GetBytes(data); handler.Send(msg); handler.Shutdown(SocketShutdown.Both); handler.Close();







Using an Asynchronous Server Socket


Asynchronous server sockets use the .NET Framework asynchronous programming model to process network service requests. The Socket class follows the standard .NET Framework asynchronous naming pattern; for example, the synchronous Accept method corresponds to the asynchronous BeginAccept and EndAccept methods.

An asynchronous server socket requires a method to begin accepting connection requests from the network, a callback method to handle the connection requests and begin receiving data from the network, and a callback method to end receiving the data. All these methods are discussed further in this section.

In the following example, to begin accepting connection requests from the network, the method StartListening initializes the Socket and then uses the BeginAccept method to start accepting new connections. The accept callback method is called when a new connection request is received on the socket. It is responsible for getting the Socket instance that will handle the connection and handing that Socket off to the thread that will process the request. The accept callback method implements the AsyncCallback delegate; it returns a void and takes a single parameter of type IAsyncResult. The following example is the shell of an accept callback method.

void acceptCallback( IAsyncResult ar) {  
    // Add the callback code here.  
}  

The BeginAccept method takes two parameters, an AsyncCallback delegate that points to the accept callback method and an object that is used to pass state information to the callback method. In the following example, the listening Socket is passed to the callback method through the state parameter. This example creates an AsyncCallback delegate and starts accepting connections from the network.

listener.BeginAccept(  
    new AsyncCallback(SocketListener.acceptCallback),   
    listener);  

Asynchronous sockets use threads from the system thread pool to process incoming connections. One thread is responsible for accepting connections, another thread is used to handle each incoming connection, and another thread is responsible for receiving data from the connection. These could be the same thread, depending on which thread is assigned by the thread pool. In the following example, the System.Threading.ManualResetEvent class suspends execution of the main thread and signals when execution can continue.

The following example shows an asynchronous method that creates an asynchronous TCP/IP socket on the local computer and begins accepting connections. It assumes that there is a global ManualResetEvent named allDone, that the method is a member of a class named SocketListener, and that a callback method named acceptCallback is defined.

public void StartListening() {  
    IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());  
    IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList[0],11000);  
  
    Console.WriteLine("Local address and port : {0}",localEP.ToString());  
  
    Socket listener = new Socket( localEP.Address.AddressFamily,  
        SocketType.Stream, ProtocolType.Tcp );  
  
    try {  
        listener.Bind(localEP);  
        listener.Listen(10);  
  
        while (true) {  
            allDone.Reset();  
  
            Console.WriteLine("Waiting for a connection...");  
            listener.BeginAccept(  
                new AsyncCallback(SocketListener.acceptCallback),   
                listener );  
  
            allDone.WaitOne();  
        }  
    } catch (Exception e) {  
        Console.WriteLine(e.ToString());  
    }  
  
    Console.WriteLine( "Closing the listener...");  
}  

The accept callback method (acceptCallback in the preceding example) is responsible for signaling the main application thread to continue processing, establishing the connection with the client, and starting the asynchronous read of data from the client. The following example is the first part of an implementation of the acceptCallback method. This section of the method signals the main application thread to continue processing and establishes the connection to the client. It assumes a global ManualResetEvent named allDone.

public void acceptCallback(IAsyncResult ar) {  
    allDone.Set();  
  
    Socket listener = (Socket) ar.AsyncState;  
    Socket handler = listener.EndAccept(ar);  
  
    // Additional code to read data goes here.    
}  

Reading data from a client socket requires a state object that passes values between asynchronous calls. The following example implements a state object for receiving a string from the remote client. It contains fields for the client socket, a data buffer for receiving data, and a StringBuilder for creating the data string sent by the client. Placing these fields in the state object allows their values to be preserved across multiple calls to read data from the client socket.

public class StateObject {  
    public Socket workSocket = null;  
    public const int BufferSize = 1024;  
    public byte[] buffer = new byte[BufferSize];  
    public StringBuilder sb = new StringBuilder();  
}  

The section of the acceptCallback method that starts receiving the data from the client socket first initializes an instance of the StateObject class and then calls the BeginReceive method to start reading the data from the client socket asynchronously.

The following example shows the complete acceptCallback method. It assumes that there is a global ManualResetEvent named allDone, that the StateObject class is defined, and that the readCallback method is defined in a class named SocketListener.

public static void acceptCallback(IAsyncResult ar) {  
    // Get the socket that handles the client request.  
    Socket listener = (Socket) ar.AsyncState;  
    Socket handler = listener.EndAccept(ar);  
  
    // Signal the main thread to continue.  
    allDone.Set();  
  
    // Create the state object.  
    StateObject state = new StateObject();  
    state.workSocket = handler;  
    handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,  
        new AsyncCallback(AsynchronousSocketListener.readCallback), state);  
}  

The final method that needs to be implemented for the asynchronous socket server is the read callback method that returns the data sent by the client. Like the accept callback method, the read callback method is an AsyncCallback delegate. This method reads one or more bytes from the client socket into the data buffer and then calls the BeginReceive method again until the data sent by the client is complete. Once the entire message has been read from the client, the string is displayed on the console and the server socket handling the connection to the client is closed.

The following sample implements the readCallback method. It assumes that the StateObject class is defined.

public static void readCallback(IAsyncResult ar) { StateObject state = (StateObject) ar.AsyncState; Socket handler = state.WorkSocket; // Read data from the client socket. int read = handler.EndReceive(ar); // Data was read from the client socket. if (read > 0) { state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,read)); handler.BeginReceive(state.buffer,0,StateObject.BufferSize, 0, new AsyncCallback(readCallback), state); } else { if (state.sb.Length > 1) { // All the data has been read from the client; // display it on the console. string content = state.sb.ToString(); Console.WriteLine("Read {0} bytes from socket.\n Data : {1}", content.Length, content); } handler.Close(); } }






Socket Code Examples


The following code examples demonstrate how to use the Socket class as a client to connect to remote network services and as a server to listen for connections from remote clients.

Synchronous Client Socket Example
Shows how to implement a synchronous Socket client that connects to a server and displays the data returned from the server.

Synchronous Server Socket Example
Shows how to implement a synchronous Socket server that accepts connections from a client and echoes back the data received from the client.

Asynchronous Client Socket Example
Shows how to implement an asynchronous Socket client that connects to a server and displays the data returned from the server.

Asynchronous Server Socket Example
Shows how to implement an asynchronous Socket server that accepts connections from a client and echoes back the data received from the client.

Sockets
Provides basic information about the System.Net.Sockets namespace and the Socket class.

Security in Network Programming
Describes how to use standard Internet security and authentication techniques.






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


Synchronous Client Socket Example


using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;  
  
public class SynchronousSocketClient {  
  
    public static void StartClient() {  
        // Data buffer for incoming data.  
        byte[] bytes = new byte[1024];  
  
        // Connect to a remote device.  
        try {  
            // Establish the remote endpoint for the socket.  
            // This example uses port 11000 on the local computer.  
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName())  
            IPAddress ipAddress = ipHostInfo.AddressList[0];  
            IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);  
  
            // Create a TCP/IP  socket.  
            Socket sender = new Socket(AddressFamily.InterNetwork,   
                SocketType.Stream, ProtocolType.Tcp );  
  
            // Connect the socket to the remote endpoint. Catch any errors.  
            try {  
                sender.Connect(remoteEP);  
  
                Console.WriteLine("Socket connected to {0}",  
                    sender.RemoteEndPoint.ToString());  
  
                // Encode the data string into a byte array.  
                byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");  
  
                // Send the data through the socket.  
                int bytesSent = sender.Send(msg);  
  
                // Receive the response from the remote device.  
                int bytesRec = sender.Receive(bytes);  
                Console.WriteLine("Echoed test = {0}",  
                    Encoding.ASCII.GetString(bytes,0,bytesRec));  
  
                // Release the socket.  
                sender.Shutdown(SocketShutdown.Both);  
                sender.Close();  
  
            } catch (ArgumentNullException ane) {  
                Console.WriteLine("ArgumentNullException : {0}",ane.ToString());  
            } catch (SocketException se) {  
                Console.WriteLine("SocketException : {0}",se.ToString());  
            } catch (Exception e) {  
                Console.WriteLine("Unexpected exception : {0}", e.ToString());  
            }  
  
        } catch (Exception e) {  
            Console.WriteLine( e.ToString());  
        }  
    }  
  
    public static int Main(String[] args) {  
        StartClient();  
        return 0;  
    }  
}






Synchronous Server Socket Example


using System;  

using System.Net;  
using System.Net.Sockets;  
using System.Text;  
  
public class SynchronousSocketListener {  
  
    // Incoming data from the client.  
    public static string data = null;  
  
    public static void StartListening() {  
        // Data buffer for incoming data.  
        byte[] bytes = new Byte[1024];  
  
        // Establish the local endpoint for the socket.  
        // Dns.GetHostName returns the name of the   
        // host running the application.  
        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(10);  
  
            // Start listening for connections.  
            while (true) {  
                Console.WriteLine("Waiting for a connection...");  
                // Program is suspended while waiting for an incoming connection.  
                Socket handler = listener.Accept();  
                data = null;  
  
                // An incoming connection needs to be processed.  
                while (true) {  
                    bytes = new byte[1024];  
                    int bytesRec = handler.Receive(bytes);  
                    data += Encoding.ASCII.GetString(bytes,0,bytesRec);  
                    if (data.IndexOf("<EOF>") > -1) {  
                        break;  
                    }  
                }  
  
                // Show the data on the console.  
                Console.WriteLine( "Text received : {0}", data);  
  
                // Echo the data back to the client.  
                byte[] msg = Encoding.ASCII.GetBytes(data);  
  
                handler.Send(msg);  
                handler.Shutdown(SocketShutdown.Both);  
                handler.Close();  
            }  
  
        } catch (Exception e) {  
            Console.WriteLine(e.ToString());  
        }  
  
        Console.WriteLine("\nPress ENTER to continue...");  
        Console.Read();  
  
    }  
  
    public static int Main(String[] args) {  
        StartListening();  
        return 0;  
    }  
}







Asynchronous Client Socket Example


The following example program creates a client that connects to a server. The client is built with an asynchronous socket, so execution of the client application is not suspended while the server returns a response. The application sends a string to the server and then displays the string returned by the server on the console.

using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Threading;  
using System.Text;  
  
// State object for receiving data from remote device.  
public class StateObject {  
    // Client socket.  
    public Socket workSocket = null;  
    // Size of receive buffer.  
    public const int BufferSize = 256;  
    // Receive buffer.  
    public byte[] buffer = new byte[BufferSize];  
    // Received data string.  
    public StringBuilder sb = new StringBuilder();  
}  
  
public class AsynchronousClient {  
    // The port number for the remote device.  
    private const int port = 11000;  
  
    // ManualResetEvent instances signal completion.  
    private static ManualResetEvent connectDone =   
        new ManualResetEvent(false);  
    private static ManualResetEvent sendDone =   
        new ManualResetEvent(false);  
    private static ManualResetEvent receiveDone =   
        new ManualResetEvent(false);  
  
    // The response from the remote device.  
    private static String response = String.Empty;  
  
    private static void StartClient() {  
        // Connect to a remote device.  
        try {  
            // Establish the remote endpoint for the socket.  
            // The name of the   
            // remote device is "host.contoso.com".  
            IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");  
            IPAddress ipAddress = ipHostInfo.AddressList[0];  
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);  
  
            // Create a TCP/IP socket.  
            Socket client = new Socket(AddressFamily.InterNetwork,  
                SocketType.Stream, ProtocolType.Tcp);  
  
            // Connect to the remote endpoint.  
            client.BeginConnect( remoteEP,   
                new AsyncCallback(ConnectCallback), client);  
            connectDone.WaitOne();  
  
            // Send test data to the remote device.  
            Send(client,"This is a test<EOF>");  
            sendDone.WaitOne();  
  
            // Receive the response from the remote device.  
            Receive(client);  
            receiveDone.WaitOne();  
  
            // Write the response to the console.  
            Console.WriteLine("Response received : {0}", response);  
  
            // Release the socket.  
            client.Shutdown(SocketShutdown.Both);  
            client.Close();  
  
        } catch (Exception e) {  
            Console.WriteLine(e.ToString());  
        }  
    }  
  
    private static void ConnectCallback(IAsyncResult ar) {  
        try {  
            // Retrieve the socket from the state object.  
            Socket client = (Socket) ar.AsyncState;  
  
            // Complete the connection.  
            client.EndConnect(ar);  
  
            Console.WriteLine("Socket connected to {0}",  
                client.RemoteEndPoint.ToString());  
  
            // Signal that the connection has been made.  
            connectDone.Set();  
        } catch (Exception e) {  
            Console.WriteLine(e.ToString());  
        }  
    }  
  
    private static void Receive(Socket client) {  
        try {  
            // Create the state object.  
            StateObject state = new StateObject();  
            state.workSocket = client;  
  
            // Begin receiving the data from the remote device.  
            client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,  
                new AsyncCallback(ReceiveCallback), state);  
        } catch (Exception e) {  
            Console.WriteLine(e.ToString());  
        }  
    }  
  
    private static void ReceiveCallback( IAsyncResult ar ) {  
        try {  
            // Retrieve the state object and the client socket   
            // from the asynchronous state object.  
            StateObject state = (StateObject) ar.AsyncState;  
            Socket client = state.workSocket;  
  
            // Read data from the remote device.  
            int bytesRead = client.EndReceive(ar);  
  
            if (bytesRead > 0) {  
                // There might be more data, so store the data received so far.  
            state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));  
  
                // Get the rest of the data.  
                client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,  
                    new AsyncCallback(ReceiveCallback), state);  
            } else {  
                // All the data has arrived; put it in response.  
                if (state.sb.Length > 1) {  
                    response = state.sb.ToString();  
                }  
                // Signal that all bytes have been received.  
                receiveDone.Set();  
            }  
        } catch (Exception e) {  
            Console.WriteLine(e.ToString());  
        }  
    }  
  
    private static void Send(Socket client, String data) {  
        // Convert the string data to byte data using ASCII encoding.  
        byte[] byteData = Encoding.ASCII.GetBytes(data);  
  
        // Begin sending the data to the remote device.  
        client.BeginSend(byteData, 0, byteData.Length, 0,  
            new AsyncCallback(SendCallback), client);  
    }  
  
    private static void SendCallback(IAsyncResult ar) {  
        try {  
            // Retrieve the socket from the state object.  
            Socket client = (Socket) ar.AsyncState;  
  
            // Complete sending the data to the remote device.  
            int bytesSent = client.EndSend(ar);  
            Console.WriteLine("Sent {0} bytes to server.", bytesSent);  
  
            // Signal that all bytes have been sent.  
            sendDone.Set();  
        } catch (Exception e) {  
            Console.WriteLine(e.ToString());  
        }  
    }  
  
    public static int Main(String[] args) {  
        StartClient();  
        return 0;  
    }  
}






Asynchronous Server Socket Example


The following example program creates a server that receives connection requests from clients. The server is built with an asynchronous socket, so execution of the server application is not suspended while it waits for a connection from a client. The application receives a string from the client, displays the string on the console, and then echoes the string back to the client. The string from the client must contain the string "<EOF>" to signal the end of the message.

using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;  
using System.Threading;  
  
// State object for reading client data asynchronously  
public class StateObject {  
    // Client  socket.  
    public Socket workSocket = null;  
    // Size of receive buffer.  
    public const int BufferSize = 1024;  
    // Receive buffer.  
    public byte[] buffer = new byte[BufferSize];  
// Received data string.  
    public StringBuilder sb = new StringBuilder();    
}  
  
public class AsynchronousSocketListener {  
    // Thread signal.  
    public static ManualResetEvent allDone = new ManualResetEvent(false);  
  
    public AsynchronousSocketListener() {  
    }  
  
    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();  
  
    }  
  
    public static void AcceptCallback(IAsyncResult ar) {  
        // Signal the main thread to continue.  
        allDone.Set();  
  
        // Get the socket that handles the client request.  
        Socket listener = (Socket) ar.AsyncState;  
        Socket handler = listener.EndAccept(ar);  
  
        // Create the state object.  
        StateObject state = new StateObject();  
        state.workSocket = handler;  
        handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,  
            new AsyncCallback(ReadCallback), state);  
    }  
  
    public static void ReadCallback(IAsyncResult ar) {  
        String content = String.Empty;  
  
        // Retrieve the state object and the handler socket  
        // from the asynchronous state object.  
        StateObject state = (StateObject) ar.AsyncState;  
        Socket handler = state.workSocket;  
  
        // Read data from the client socket.   
        int bytesRead = handler.EndReceive(ar);  
  
        if (bytesRead > 0) {  
            // There  might be more data, so store the data received so far.  
            state.sb.Append(Encoding.ASCII.GetString(  
                state.buffer,0,bytesRead));  
  
            // Check for end-of-file tag. If it is not there, read   
            // more data.  
            content = state.sb.ToString();  
            if (content.IndexOf("<EOF>") > -1) {  
                // All the data has been read from the   
                // client. Display it on the console.  
                Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",  
                    content.Length, content );  
                // Echo the data back to the client.  
                Send(handler, content);  
            } else {  
                // Not all data received. Get more.  
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
                new AsyncCallback(ReadCallback), state);  
            }  
        }  
    }  
  
    private static void Send(Socket handler, String data) {  
        // Convert the string data to byte data using ASCII encoding.  
        byte[] byteData = Encoding.ASCII.GetBytes(data);  
  
        // Begin sending the data to the remote device.  
        handler.BeginSend(byteData, 0, byteData.Length, 0,  
            new AsyncCallback(SendCallback), handler);  
    }  
  
    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());  
        }  
    }  
  
    public static int Main(String[] args) {  
        StartListening();  
        return 0;  
    }  
}






SocketAsyncEventArgs Class


https://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs(v=vs.110).aspx


Represents an asynchronous socket operation.

Namespace:   System.Net.Sockets
Assembly:  System (in System.dll)

Inheritance Hierarchy

System.Object
  System.EventArgs
    System.Net.Sockets.SocketAsyncEventArgs



Remarks

The SocketAsyncEventArgs class is part of a set of enhancements to the System.Net.Sockets.Socket class that provide an alternative asynchronous pattern that can be used by specialized high-performance socket applications. This class was specifically designed for network server applications that require high performance. An application can use the enhanced asynchronous pattern exclusively or only in targeted hot areas (for example, when receiving large amounts of data).

The main feature of these enhancements is the avoidance of the repeated allocation and synchronization of objects during high-volume asynchronous socket I/O. The Begin/End design pattern currently implemented by the System.Net.Sockets.Socket class requires a System.IAsyncResult object be allocated for each asynchronous socket operation.

In the new System.Net.Sockets.Socket class enhancements, asynchronous socket operations are described by reusable SocketAsyncEventArgs objects allocated and maintained by the application. High-performance socket applications know best the amount of overlapped socket operations that must be sustained. The application can create as many of the SocketAsyncEventArgs objects that it needs. For example, if a server application needs to have 15 socket accept operations outstanding at all times to support incoming client connection rates, it can allocate 15 reusable SocketAsyncEventArgs objects for that purpose.

The pattern for performing an asynchronous socket operation with this class consists of the following steps:

  1. Allocate a new SocketAsyncEventArgs context object, or get a free one from an application pool.

  2. Set properties on the context object to the operation about to be performed (the completion callback method, the data buffer, the offset into the buffer, and the maximum amount of data to transfer, for example).

  3. Call the appropriate socket method (xxxAsync) to initiate the asynchronous operation.

  4. If the asynchronous socket method (xxxAsync) returns true, in the callback, query the context properties for completion status.

  5. If the asynchronous socket method (xxxAsync) returns false, the operation completed synchronously. The context properties may be queried for the operation result.

  6. Reuse the context for another operation, put it back in the pool, or discard it.

The lifetime of the new asynchronous socket operation context object is determined by references by the application code and asynchronous I/O references. It is not necessary for the application to retain a reference to an asynchronous socket operation context object after it is submitted as a parameter to one of the asynchronous socket operation methods. It will remain referenced until the completion callback returns. However it is advantageous for the application to retain the reference to the context so that it can be reused for a future asynchronous socket operation.

Examples

The following code example implements the connection logic for the socket server that uses the SocketAsyncEventArgs class. After accepting a connection, all data read from the client is sent back to the client. The read and echo back to the client pattern is continued until the client disconnects. The BufferManager class that is used by this example is displayed in the code example for the SetBuffer(Byte[], Int32, Int32) method. The SocketAsyncEventArgsPool class that is used in this example is displayed in the code example for the SocketAsyncEventArgs constructor.

// Implements the connection logic for the socket server.  
// After accepting a connection, all data read from the client 
// is sent back to the client. The read and echo back to the client pattern 
// is continued until the client disconnects.
class Server
{
    private int m_numConnections;   // the maximum number of connections the sample is designed to handle simultaneously 
    private int m_receiveBufferSize;// buffer size to use for each socket I/O operation 
    BufferManager m_bufferManager;  // represents a large reusable set of buffers for all socket operations
    const int opsToPreAlloc = 2;    // read, write (don't alloc buffer space for accepts)
    Socket listenSocket;            // the socket used to listen for incoming connection requests
    // pool of reusable SocketAsyncEventArgs objects for write, read and accept socket operations
    SocketAsyncEventArgsPool m_readWritePool;
    int m_totalBytesRead;           // counter of the total # bytes received by the server
    int m_numConnectedSockets;      // the total number of clients connected to the server 
    Semaphore m_maxNumberAcceptedClients;

    // Create an uninitialized server instance.  
    // To start the server listening for connection requests
    // call the Init method followed by Start method 
    //
    // <param name="numConnections">the maximum number of connections the sample is designed to handle simultaneously</param>
    // <param name="receiveBufferSize">buffer size to use for each socket I/O operation</param>
    public Server(int numConnections, int receiveBufferSize)
    {
        m_totalBytesRead = 0;
        m_numConnectedSockets = 0;
        m_numConnections = numConnections;
        m_receiveBufferSize = receiveBufferSize;
        // allocate buffers such that the maximum number of sockets can have one outstanding read and 
        //write posted to the socket simultaneously  
        m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc,
            receiveBufferSize);

        m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
        m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections); 
    }

    // Initializes the server by preallocating reusable buffers and 
    // context objects.  These objects do not need to be preallocated 
    // or reused, but it is done this way to illustrate how the API can 
    // easily be used to create reusable objects to increase server performance.
    //
    public void Init()
    {
        // Allocates one large byte buffer which all I/O operations use a piece of.  This gaurds 
        // against memory fragmentation
        m_bufferManager.InitBuffer();

        // preallocate pool of SocketAsyncEventArgs objects
        SocketAsyncEventArgs readWriteEventArg;

        for (int i = 0; i < m_numConnections; i++)
        {
            //Pre-allocate a set of reusable SocketAsyncEventArgs
            readWriteEventArg = new SocketAsyncEventArgs();
            readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
            readWriteEventArg.UserToken = new AsyncUserToken();

            // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object
            m_bufferManager.SetBuffer(readWriteEventArg);

            // add SocketAsyncEventArg to the pool
            m_readWritePool.Push(readWriteEventArg);
        }

    }

    // Starts the server such that it is listening for 
    // incoming connection requests.    
    //
    // <param name="localEndPoint">The endpoint which the server will listening 
    // for connection requests on</param>
    public void Start(IPEndPoint localEndPoint)
    {
        // create the socket which listens for incoming connections
        listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        listenSocket.Bind(localEndPoint);
        // start the server with a listen backlog of 100 connections
        listenSocket.Listen(100);

        // post accepts on the listening socket
        StartAccept(null);            

        //Console.WriteLine("{0} connected sockets with one outstanding receive posted to each....press any key", m_outstandingReadCount);
        Console.WriteLine("Press any key to terminate the server process....");
        Console.ReadKey();
    }


    // Begins an operation to accept a connection request from the client 
    //
    // <param name="acceptEventArg">The context object to use when issuing 
    // the accept operation on the server's listening socket</param>
    public void StartAccept(SocketAsyncEventArgs acceptEventArg)
    {
        if (acceptEventArg == null)
        {
            acceptEventArg = new SocketAsyncEventArgs();
            acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
        }
        else
        {
            // socket must be cleared since the context object is being reused
            acceptEventArg.AcceptSocket = null;
        }

        m_maxNumberAcceptedClients.WaitOne();
        bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
        if (!willRaiseEvent)
        {
            ProcessAccept(acceptEventArg);
        }
    }

    // This method is the callback method associated with Socket.AcceptAsync 
    // operations and is invoked when an accept operation is complete
    //
    void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
    {
        ProcessAccept(e);
    }

    private void ProcessAccept(SocketAsyncEventArgs e)
    {
        Interlocked.Increment(ref m_numConnectedSockets);
        Console.WriteLine("Client connection accepted. There are {0} clients connected to the server",
            m_numConnectedSockets);

        // Get the socket for the accepted client connection and put it into the 
        //ReadEventArg object user token
        SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
        ((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket;

        // As soon as the client is connected, post a receive to the connection
        bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
        if(!willRaiseEvent){
            ProcessReceive(readEventArgs);
        }

        // Accept the next connection request
        StartAccept(e);
    }

    // This method is called whenever a receive or send operation is completed on a socket 
    //
    // <param name="e">SocketAsyncEventArg associated with the completed receive operation</param>
    void IO_Completed(object sender, SocketAsyncEventArgs e)
    {
        // determine which type of operation just completed and call the associated handler
        switch (e.LastOperation)
        {
            case SocketAsyncOperation.Receive:
                ProcessReceive(e);
                break;
            case SocketAsyncOperation.Send:
                ProcessSend(e);
                break;
            default:
                throw new ArgumentException("The last operation completed on the socket was not a receive or send");
        }       

    }

    // This method is invoked when an asynchronous receive operation completes. 
    // If the remote host closed the connection, then the socket is closed.  
    // If data was received then the data is echoed back to the client.
    //
    private void ProcessReceive(SocketAsyncEventArgs e)
    {
        // check if the remote host closed the connection
        AsyncUserToken token = (AsyncUserToken)e.UserToken;
        if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
        {
            //increment the count of the total bytes receive by the server
            Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
            Console.WriteLine("The server has read a total of {0} bytes", m_totalBytesRead);

            //echo the data received back to the client
            e.SetBuffer(e.Offset, e.BytesTransferred);
            bool willRaiseEvent = token.Socket.SendAsync(e);
            if (!willRaiseEvent)
            {
                ProcessSend(e);
            }

        }
        else
        {
            CloseClientSocket(e);
        }
    }

    // This method is invoked when an asynchronous send operation completes.  
    // The method issues another receive on the socket to read any additional 
    // data sent from the client
    //
    // <param name="e"></param>
    private void ProcessSend(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // done echoing data back to the client
            AsyncUserToken token = (AsyncUserToken)e.UserToken;
            // read the next block of data send from the client
            bool willRaiseEvent = token.Socket.ReceiveAsync(e);
            if (!willRaiseEvent)
            {
                ProcessReceive(e);
            }
        }
        else
        {
            CloseClientSocket(e);
        }
    }

    private void CloseClientSocket(SocketAsyncEventArgs e)
    {
        AsyncUserToken token = e.UserToken as AsyncUserToken;

        // close the socket associated with the client
        try
        {
            token.Socket.Shutdown(SocketShutdown.Send);
        }
        // throws if client process has already closed
        catch (Exception) { }
        token.Socket.Close();

        // decrement the counter keeping track of the total number of clients connected to the server
        Interlocked.Decrement(ref m_numConnectedSockets);
        m_maxNumberAcceptedClients.Release();
        Console.WriteLine("A client has been disconnected from the server. There are {0} clients connected to the server", m_numConnectedSockets);

        // Free the SocketAsyncEventArg so they can be reused by another client
        m_readWritePool.Push(e);
    }

}






TcpListener Class


Listens for connections from TCP network clients.

Namespace:   System.Net.Sockets
Assembly:  System (in System.dll)

Inheritance Hierarchy

System.Object
  System.Net.Sockets.TcpListener

Remarks

The TcpListener class provides simple methods that listen for and accept incoming connection requests in blocking synchronous mode. You can use either a TcpClient or a Socket to connect with a TcpListener. Create a TcpListener using an IPEndPoint, a Local IP address and port number, or just a port number. Specify Any for the local IP address and 0 for the local port number if you want the underlying service provider to assign those values for you. If you choose to do this, you can use the LocalEndpoint property to identify the assigned information, after the socket has connected.

Use the Start method to begin listening for incoming connection requests. Start will queue incoming connections until you either call the Stop method or it has queued MaxConnections. Use either AcceptSocket or AcceptTcpClient to pull a connection from the incoming connection request queue. These two methods will block. If you want to avoid blocking, you can use the Pending method first to determine if connection requests are available in the queue.

Call the Stop method to close the TcpListener.

System_CAPS_noteNote

The Stop method does not close any accepted connections. You are responsible for closing these separately.

Examples

The following code example creates a TcpListener.

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

class MyTcpListener
{
  public static void Main()
  { 
    TcpListener server=null;   
    try
    {
      // Set the TcpListener on port 13000.
      Int32 port = 13000;
      IPAddress localAddr = IPAddress.Parse("127.0.0.1");

      // TcpListener server = new TcpListener(port);
      server = new TcpListener(localAddr, port);

      // Start listening for client requests.
      server.Start();

      // Buffer for reading data
      Byte[] bytes = new Byte[256];
      String data = null;

      // Enter the listening loop.
      while(true) 
      {
        Console.Write("Waiting for a connection... ");

        // Perform a blocking call to accept requests.
        // You could also user server.AcceptSocket() here.
        TcpClient client = server.AcceptTcpClient();            
        Console.WriteLine("Connected!");

        data = null;

        // Get a stream object for reading and writing
        NetworkStream stream = client.GetStream();

        int i;

        // Loop to receive all the data sent by the client.
        while((i = stream.Read(bytes, 0, bytes.Length))!=0) 
        {   
          // Translate data bytes to a ASCII string.
          data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
          Console.WriteLine("Received: {0}", data);

          // Process the data sent by the client.
          data = data.ToUpper();

          byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

          // Send back a response.
          stream.Write(msg, 0, msg.Length);
          Console.WriteLine("Sent: {0}", data);            
        }

        // Shutdown and end connection
        client.Close();
      }
    }
    catch(SocketException e)
    {
      Console.WriteLine("SocketException: {0}", e);
    }
    finally
    {
       // Stop listening for new clients.
       server.Stop();
    }


    Console.WriteLine("\nHit enter to continue...");
    Console.Read();
  }   
} 

See TcpClient for a client example.










TcpClient Class


Provides client connections for TCP network services.

Namespace:   System.Net.Sockets
Assembly:  System (in System.dll)

Inheritance Hierarchy

System.Object
  System.Net.Sockets.TcpClient



Remarks

The TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode.

In order for TcpClient to connect and exchange data, a TcpListener or Socket created with the TCP ProtocolType must be listening for incoming connection requests. You can connect to this listener in one of the following two ways:

  • Create a TcpClient and call one of the three available Connect methods.

  • Create a TcpClient using the host name and port number of the remote host. This constructor will automatically attempt a connection.

System_CAPS_noteNote

If you want to send connectionless datagrams in synchronous blocking mode, use the UdpClient class.

Notes to Inheritors:

To send and receive data, use the GetStream method to obtain a NetworkStream. Call the Write and Read methods of the NetworkStream to send and receive data with the remote host. Use the Close method to release all resources associated with the TcpClient.

Examples

The following code example establishes a TcpClient connection.

static void Connect(String server, String message) 
{
  try 
  {
    // Create a TcpClient.
    // Note, for this client to work you need to have a TcpServer 
    // connected to the same address as specified by the server, port
    // combination.
    Int32 port = 13000;
    TcpClient client = new TcpClient(server, port);

    // Translate the passed message into ASCII and store it as a Byte array.
    Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);         

    // Get a client stream for reading and writing.
   //  Stream stream = client.GetStream();

    NetworkStream stream = client.GetStream();

    // Send the message to the connected TcpServer. 
    stream.Write(data, 0, data.Length);

    Console.WriteLine("Sent: {0}", message);         

    // Receive the TcpServer.response.

    // Buffer to store the response bytes.
    data = new Byte[256];

    // String to store the response ASCII representation.
    String responseData = String.Empty;

    // Read the first batch of the TcpServer response bytes.
    Int32 bytes = stream.Read(data, 0, data.Length);
    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
    Console.WriteLine("Received: {0}", responseData);         

    // Close everything.
    stream.Close();         
    client.Close();         
  } 
  catch (ArgumentNullException e) 
  {
    Console.WriteLine("ArgumentNullException: {0}", e);
  } 
  catch (SocketException e) 
  {
    Console.WriteLine("SocketException: {0}", e);
  }

  Console.WriteLine("\n Press Enter to continue...");
  Console.Read();
}








'프로그래밍 > C#' 카테고리의 다른 글

Common I/O Tasks  (0) 2017.03.15
Thread 관련  (0) 2017.03.05
Using the Visual Studio Development Environment for C#  (0) 2017.02.14
Getting Started with C#  (0) 2017.02.13
클래스 종류 헤드라인  (0) 2017.01.04
:
Posted by 지훈2