我已经实现了C#tcp-ip客户端(同步和异步读取套接字)。 每次SocketException之后,我都会自动重新连接与服务器的连接。
然后我在windows中测试了客户端与ncat的通信。在这里,如果我杀了ncat,它会在C#客户端抛出SocketException,一切都按照我想象的方式工作。
但后来我用linux中的ncat测试了它 - 这里的通讯工作正常,但如果我杀了ncat服务器(在Windows上的设置相同 - ncat -l -k -p xxxx ),在回调中接收大量空数据(零B)(或在同步版本中等待套接字)并且不抛出任何异常。
有一点是Windows / Unix版本的ncat可能有不同的行为。但是我仍然需要为任何版本的tcp-ip服务器解决这种奇怪的行为。
/* ------------------------------------------------------------------------- */
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 }
}
谢谢!
答案 0 :(得分:0)
<强>解决强>
在OnDataReceived回调中,我检查传入数据的数量,所以我这样做:
if (iRx == 0)
throw new SocketException(Convert.ToInt16(SocketError.HostDown));
答案 1 :(得分:0)
TCP接收器永远无法获得远程连接的确切状态。根据TCP / IP堆栈实现,终止进程将发送FIN(接收为零)或RST(获取异常)。还有其他条件,应用程序完全不知道连接断开。假设如果强制重置远程系统或拔掉电缆线或更改IP地址,则在发送一些数据之前,您无法知道连接是否断开。如果您的应用程序需要知道连接的状态,它可以每1分钟发送一些虚拟数据,以确保连接存活。