My first implementation of a client/server application Well, it's 2 applications really. Each one does its own stuff on the front-end. It's the networking that I'm most concerned about.

The Server starts listening for connections on the specified port as soon as it starts up. When clients connect, it accepts, serves and boots them in turn (or rather that's the idea but I think there's a flaw in what I've got here).

The server is multithreaded to handle requests on new threads so as to avoid locking its UI while it works.

public void StartListening()
{
    TcpListener Svr = null;

    Int32 Port = 13000;
    IPAddress LocalAddress = IPAddress.Parse("127.0.0.1");

    Svr = new TcpListener(LocalAddress, Port);

    Svr.Start();

    Byte[] Buffer = new Byte[1024];

    Task.Run(() =&gt;
    {
        while (true)
        {
            TcpClient Client = Svr.AcceptTcpClient();
            NetworkStream Stream = Client.GetStream();

            byte[] Response = HandleClientData(Stream, Buffer, Client);

            Stream.Write(Response, 0, Response.Length);

            Client.Close();
        }
    });
}


The function that reads and works with the data HandleClientData(NetworkStream, byte[], TcpClient) looks like this:

private byte[] HandleClientData(NetworkStream stream, Byte[] buffer, TcpClient client)
{
    int i;

    byte[] value = null;

    while ((i = stream.Read(buffer, 0, buffer.Length)) != 0)
    {
        string ClientData = Encoding.ASCII.GetString(buffer, 0, i);

        // do stuff with the client data and send a response
        value = ...;
    }
return value;
}


The Client is much the same, except its not listening for connections. It's only job is to send requests to the server and display the result that the server sends back:

public class _TcpClient
{
    public const string Server = "127.0.0.1";
    public const int Port = 13000;

    public string SendData(string data)
    {
        try
        {
            string Response = String.Empty;
            using (TcpClient Client = new TcpClient())
            {
                Client.Connect(Server, Port);

                using (NetworkStream Stream = new NetworkStream(Client.Client))
                {
                    Stream.Write(Encoding.ASCII.GetBytes(data), 0, 256);

                    int ByteRead = 0;
                    byte[] Buffer = new Byte[256];

                    while (ByteRead &gt; 0)
                    {
                        ByteRead = Stream.Read(Buffer, 0, 256);
                        Response += Encoding.ASCII.GetString(Buffer, 0, ByteRead);
                    }
                }
            }

            return Response;
        }
        catch (Exception ex)
        {
            return String.Format("ERR,{0}", ex.Message);
        }
    }
}


To keep things simple, all comms between client and server send and receive delimited strings which are read by each component and handled in a particular way for each.

Is this a fairly decent implementation or a client/server program? How can I improve this or make it more functional?
Naming


Usually, local variables start with a small letter.


StartListening


If the method is called multiple times, it will throw an exception that the endpoint is already in use. Not very robust.
Task.Run(action) uses a thread from the thread pool. Those threads are usually pooled for short running actions. TaskFactory.StartNew(action, TaskCreationOptions.LongRunning) creates a new thread to run the action in. That is more appropriated for long running tasks.
You should use try / catch or using to ensure that the client will be disposed, even if an error occurs.
You should provide a way to shut down the server - closing the application is IMHO not the right way.


HandleClientData


If the incoming data size is bigger than 1024, only the last chunk is received. You would probably add the chunk to the string: clientData += Encoding.ASCII.GetString(buffer, 0, i);