I have implemented C# tcp-ip client (both synchronous & async reading socket). After each SocketException, I'm automatically reconnecting connection with server.
Then I have tested communication of client with ncat in windows. Here, if I kill ncat, it throws SocketException in C# client and everything works as I imagine.
But then I have tested it with ncat in linux - here communication works OK, but if I kill ncat server (the same settings like at Windows - ncat -l -k -p xxxx), huge amount of empty data (zero B) is received in callback (or waiting on socket in sync version) and no exception is thrown.
One thing is that Windows / Unix version of ncat can have different behavior. But still I need to solve this weird behavior for any version of tcp-ip server.
/* ------------------------------------------------------------------------- */
public void WaitForData()
{
try
{
if (callback == null)
callback = new AsyncCallback(OnDataReceived);
SocketPacket packet = new SocketPacket();
packet.thisSocket = socket;
m_result = socket.BeginReceive
(packet.dataBuffer, 0, 256,
SocketFlags.None, callback, packet);
}
catch (SocketException ex) { ///reconnecting }
}
/* ------------------------------------------------------------------------- */
public class SocketPacket
{
public System.Net.Sockets.Socket thisSocket;
public byte[] dataBuffer = new byte[256];
}
/* ------------------------------------------------------------------------- */
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.thisSocket.EndReceive(asyn);
char[] chars = new char[iRx];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
string szData = new string(chars);
szData = szData.Replace("\n", String.Empty);
processMessage(szData);
WaitForData();
}
catch (ObjectDisposedException) { }
catch (SocketException ex) { ///reconnecting }
}
Thank you!
Solved
In OnDataReceived callback, I check amount of incoming data, so I do:
if (iRx == 0)
throw new SocketException(Convert.ToInt16(SocketError.HostDown));