I wrote a TCP Socket server and client a few months ago in my current project and they've been working flawlessly since then. But as of today I simply cannot get a connection between two machines that has been communicating without a hickup for a long time.
The setup is very straight forward: Two machines ('A' and 'B') are connected directly via an ethernet cable (no switch in between). Machine 'A' is also connected to my home network which allows for Internet access. Machine 'B' is only connected to 'A'. I am running the TCP server on 'B' and the client on 'A'.
I'm using the asynchronous .NET Socket
features (BeginAccept
etc on the server end and BeginConnect
etc in the client end). Having debugged both ends I can only confirm that the server end never seems to get a call from the client. I haven't touched the code and it still works between other machines.
Also, there's no other comms problems between the two machines. I'm using Input Director to share one set of keyboard/mouse and normal UNC paths works fine to browse one machine from the other.
I have tested different ports and I've brought down the firewalls on both sides for good measure. I have released/renewed the connections on both sides, rebooted both machines and every other dummy option I can think of.
I confess I'm not terribly network savvy so I'd very much appreciate a few hints on what to look for next as I'm now out of ideas on what to check next. (I'm pretty sure it's gotta be something really stupid I've just overlooked. ;O)
EDIT (sample 'spike' code)
On request I adapted Microsoft's sample Socket code and compressed it a bit (below). I then tested running both server and client ends on machine 'B' which worked fine but on machine 'A' the same thing happened. The client got no contact with the server end. Here's the code:
public static class SocketServer
{
private class StateObject
{
public Socket _workSocket;
public const int BufferSize = 1024;
public readonly byte[] _buffer = new byte[BufferSize];
public readonly StringBuilder _sb = new StringBuilder();
}
private static readonly ManualResetEvent _s_allDone = new ManualResetEvent(false);
public static void StartListening()
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, 11000);
var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
_s_allDone.Reset();
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(acceptCallback, listener);
_s_allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static void acceptCallback(IAsyncResult ar)
{
_s_allDone.Set();
var listener = (Socket)ar.AsyncState;
var handler = listener.EndAccept(ar);
var state = new StateObject {_workSocket = handler};
handler.BeginReceive(state._buffer, 0, StateObject.BufferSize, 0, readCallback, state);
}
private static void readCallback(IAsyncResult ar)
{
var state = (StateObject)ar.AsyncState;
var handler = state._workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead <= 0)
return;
state._sb.Append(Encoding.ASCII.GetString(state._buffer, 0, bytesRead));
var content = state._sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
}
else
{
handler.BeginReceive(state._buffer, 0, StateObject.BufferSize, 0, readCallback, state);
}
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
public static class SocketClient
{
private class StateObject
{
public Socket _workSocket;
public const int BufferSize = 256;
public readonly byte[] _receiveBuffer = new byte[BufferSize];
public readonly StringBuilder _sb = new StringBuilder();
}
private const int RemotePort = 11000;
private static readonly ManualResetEvent _s_connectDone = new ManualResetEvent(false);
private static readonly ManualResetEvent _s_sendDone = new ManualResetEvent(false);
private static readonly ManualResetEvent _s_receiveDone = new ManualResetEvent(false);
// The response from the remote device.
private static String _s_response = String.Empty;
private static void startClient()
{
try
{
_s_connectDone.WaitOne(2000); // <-- gives server time to boot when on same machine
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var remoteEndPoint = new IPEndPoint(ipAddress, RemotePort);
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEndPoint, connectCallback, client);
_s_connectDone.WaitOne();
send(client, "This is a test<EOF>");
_s_sendDone.WaitOne();
receive(client);
_s_receiveDone.WaitOne();
Console.WriteLine("Response received : {0}", _s_response);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void connectCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint);
_s_connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void receive(Socket client)
{
try
{
var state = new StateObject {_workSocket = client};
client.BeginReceive(state._receiveBuffer, 0, StateObject.BufferSize, 0, receiveCallback, state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void receiveCallback(IAsyncResult ar)
{
try
{
var state = (StateObject)ar.AsyncState;
var client = state._workSocket;
var bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state._sb.Append(Encoding.ASCII.GetString(state._receiveBuffer, 0, bytesRead));
client.BeginReceive(state._receiveBuffer, 0, StateObject.BufferSize, 0, receiveCallback, state);
}
else
{
if (state._sb.Length > 1)
{
_s_response = state._sb.ToString();
}
_s_receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void send(Socket client, String data)
{
var byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0, sendCallback, client);
}
private static void sendCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
var bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
_s_sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main()
{
startClient();
return 0;
}
}