Here is the solution I settled on:
Server:
public class Listener
{
private TcpListener _listener;
private TcpClient _client;
public void Start()
{
_listener = new TcpListener(IPAddress.Loopback, 17999);
_listener.Start();
_listener.BeginAcceptTcpClient(new AsyncCallback(AcceptTcpClientCallback), _listener);
}
private void AcceptTcpClientCallback(IAsyncResult ar)
{
try
{
Debug.WriteLine("Accepted tcp client callback");
_client = _listener.EndAcceptTcpClient(ar);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
public void Write(string data)
{
try
{
NetworkStream ns = _client.GetStream();
byte[] buffer = Encoding.ASCII.GetBytes(data);
ns.Write(buffer, 0, buffer.Length);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
}
And the client:
public class Client
{
private TcpClient _client;
private byte[] _buffer;
public void Start()
{
try
{
_client = new TcpClient();
_client.BeginConnect(IPAddress.Loopback, 17999, new AsyncCallback(ConnectCallback), _client);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
NetworkStream ns = _client.GetStream();
_buffer = new byte[_client.ReceiveBufferSize];
ns.BeginRead(_buffer, 0, _buffer.Length, new AsyncCallback(ReadCallback), null);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
NetworkStream ns = _client.GetStream();
int read = ns.EndRead(ar);
string data = Encoding.ASCII.GetString(_buffer, 0, read);
var res = data.Split(new [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var r in res)
{
Debug.WriteLine(r); // process messages
}
ns.BeginRead(_buffer, 0, _buffer.Length, ReadCallback, _client);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
}
Where messages from the server to the client are formed as follows:
string message = "This is a message" + "\r\n";
_listener.Send(message);
I like this alternative for its simplicity. Its a lot shorter and (to me at least) much easier to manage.
HTH