具有零数据的C#套接字阻塞
我已经实现了C#tcp ip客户端(同步和异步读取套接字)。 每次SocketException之后,我都会自动重新连接到服务器 然后在windows下测试了客户端与ncat的通信。在这里,如果我杀死ncat,它会在C#client中抛出SocketException,一切都按照我的想象进行 但是我已经在linux中用ncat测试了它-这里的通信工作正常,但是如果我杀死ncat服务器(与在Windows上相同的设置-ncat-l-k-pxxxx),在回调(或在同步版本中等待套接字)中会收到大量空数据(零B),并且不会引发异常 一件事是Windows/Unix版本的ncat可以有不同的行为。但我仍然需要解决任何版本的tcp ip服务器的这种奇怪行为具有零数据的C#套接字阻塞,c#,sockets,tcp,blocking,blocked,C#,Sockets,Tcp,Blocking,Blocked,我已经实现了C#tcp ip客户端(同步和异步读取套接字)。 每次SocketException之后,我都会自动重新连接到服务器 然后在windows下测试了客户端与ncat的通信。在这里,如果我杀死ncat,它会在C#client中抛出SocketException,一切都按照我的想象进行 但是我已经在linux中用ncat测试了它-这里的通信工作正常,但是如果我杀死ncat服务器(与在Windows上相同的设置-ncat-l-k-pxxxx),在回调(或在同步版本中等待套接字)中会收到大量空
/* ------------------------------------------------------------------------- */
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 }
}
谢谢大家! 已解决 在OnDataReceived回调中,我检查传入数据的数量,因此:
if (iRx == 0)
throw new SocketException(Convert.ToInt16(SocketError.HostDown));
TCP接收器永远无法获得远程连接的确切状态。终止进程将根据TCP/IP堆栈实现发送FIN(接收为零)或RST(获取异常)。还有一种情况是应用程序完全不知道连接中断。假设远程系统被强制重置,或者电缆被拔出,或者IP地址被更改,在发送一些数据之前,您无法知道连接是否断开。如果您的应用程序需要知道连接的状态,它可以每1分钟发送一些虚拟数据,以确保连接处于活动状态。通常,向失效的服务器进程发送数据的客户端将返回FIN或RST,从而关闭连接。但是,如果服务器突然终止,或者网络失去连接,而客户端不尝试发送任何内容,那么它很容易挂起等待数据。你应该让你的客户适应这些问题。(超时、定期保留等…)我建议您发布代码,这样我们就可以看到客户端的行为。问题是,我不知道如何检查任何活动的内容,因为所有内容似乎都已连接,但服务器已关闭。是的,在这种情况下,我尝试发送数据,并且处理过程也没有异常。我通过检测传入数据是否不为零来解决这个问题,无论如何我抛出异常。但我想这只是一种解决办法。。。