Simple TCP/IP Echo Server & Client Application in C#

1. TCP Server

 

The server’s job is to set up an endpoint for clients to connect to and passively wait for connections.

The typical TCP server goes through two steps:

1. Construct a TcpListener instance, specifying the local address and port, and call the Start() method.

This socket listens for incoming connections on the specified port.

2. Repeatedly:
■ Call the AcceptTcpClient() method of TcpListener to get the next incoming
   client connection. Upon establishment of a new client connection, an instance of
   TcpClient for the new connection is created and returned by the AcceptTcp-
   Client() call.
■ Communicate with the client using the Read() and Write() methods of TcpClient’s
   NetworkStream.
■ Close the new client socket connection and stream using the Close() methods of
   NetworkStream and TcpClient.

TcpEchoServer.cs

using System; // For Console, Int32, ArgumentException, Environment
using System.Net; // For IPAddress
using System.Net.Sockets; // For TcpListener, TcpClient

class TcpEchoServer 
{
    private const int BUFSIZE = 32; // Size of receive buffer
    
    static void Main(string[] args) 
    {
        if (args.Length > 1) // Test for correct # of args
            throw new ArgumentException("Parameters: [<Port>]");
        
        int servPort = (args.Length == 1) ? Int32.Parse(args[0]): 7;

        TcpListener listener = null;

        try 
        {
            // Create a TCPListener to accept client connections
            listener = new TcpListener(IPAddress.Any, servPort);
            listener.Start();
        } 
        catch (SocketException se) 
        {
            Console.WriteLine(se.ErrorCode + ": " + se.Message);
            Environment.Exit(se.ErrorCode);
        }

        byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
        int bytesRcvd; // Received byte count

        for (;;) 
        { 
            // Run forever, accepting and servicing connections
            TcpClient client = null;
            NetworkStream netStream = null;
            try 
            {
                client = listener.AcceptTcpClient(); // Get client connection
                netStream = client.GetStream();
                Console.Write("Handling client - ");

                // Receive until client closes connection, indicated by 0 return value
                int totalBytesEchoed = 0;
                while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) 
                {
                    netStream.Write(rcvBuffer, 0, bytesRcvd);
                    totalBytesEchoed += bytesRcvd;
                }
                Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);

                // Close the stream and socket. We are done with this client!
                netStream.Close();
                client.Close();
            } 
            catch (Exception e) 
            {
                Console.WriteLine(e.Message);
                netStream.Close();
            }
        }
    }
}

The TcpListener listens for client connection requests on the port specified in the constructor.

Be careful to use a port that is not in use by another application, or a SocketException will be thrown.

Loop forever, iteratively handling incoming connections.

Receive and repeat data until the client closes.

Close the client stream and socket.

 

TcpEchoClient.cs

using System; // For String, Int32, Console, ArgumentException
using System.Text; // For Encoding
using System.IO; // For IOException
using System.Net.Sockets; // For TcpClient, NetworkStream, SocketException

class TcpEchoClient 
{
    static void Main(string[] args) 
    {
        if ((args.Length < 2) || (args.Length > 3)) 
        { 
            // Test for correct # of args
            throw new ArgumentException("Parameters: <Server> <Word> [<Port>]");
        }
        
        String server = args[0]; // Server name or IP address

        // Convert input String to bytes
        byte[] byteBuffer = Encoding.ASCII.GetBytes(args[1]);

        // Use port argument if supplied, otherwise default to 7
        int servPort = (args.Length == 3) ? Int32.Parse(args[2]) : 7;

        TcpClient client = null;
        NetworkStream netStream = null;

        try 
        {
            // Create socket that is connected to server on specified port
            client = new TcpClient(server, servPort);
            Console.WriteLine("Connected to server... sending echo string");
            netStream = client.GetStream();

            // Send the encoded string to the server
            netStream.Write(byteBuffer, 0, byteBuffer.Length);
            Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length);
            int totalBytesRcvd = 0; // Total bytes received so far
            int bytesRcvd = 0; // Bytes received in last read

            // Receive the same string back from the server
            while (totalBytesRcvd < byteBuffer.Length) 
            {
                if ((bytesRcvd = netStream.Read(byteBuffer, totalBytesRcvd, byteBuffer.Length - totalBytesRcvd)) == 0) 
                {
                    Console.WriteLine("Connection closed prematurely.");
                    break;
                }
                totalBytesRcvd += bytesRcvd;
            }
            Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd,
            Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.Message);
        } 
        finally 
        {
            netStream.Close();
            client.Close();
        }
    }
}

 

posted @ 2015-08-10 11:11  Master HaKu  阅读(3148)  评论(0编辑  收藏  举报