C# TcpListener/TcpClient在某些情况下停止处理数据
我有一个问题,根据两个网络设备的启动顺序,我似乎失去了在一端接收数据的能力 该设置是一个用C#(.NET4.0)编写的小型服务器,它监听来自工业扫描仪的特定端口的数据,并通过TCP进行通信。扫描仪与服务器应用程序连接良好,将发送服务器接收和处理的小块数据(序列号)。但是,在扫描仪上重新启动(实际上,循环电源并不能正常关闭其连接)会导致服务器停止处理数据。事件顺序以及导致问题的关键网络流量如下所示:C# TcpListener/TcpClient在某些情况下停止处理数据,c#,.net,networking,tcp,tcpclient,C#,.net,Networking,Tcp,Tcpclient,我有一个问题,根据两个网络设备的启动顺序,我似乎失去了在一端接收数据的能力 该设置是一个用C#(.NET4.0)编写的小型服务器,它监听来自工业扫描仪的特定端口的数据,并通过TCP进行通信。扫描仪与服务器应用程序连接良好,将发送服务器接收和处理的小块数据(序列号)。但是,在扫描仪上重新启动(实际上,循环电源并不能正常关闭其连接)会导致服务器停止处理数据。事件顺序以及导致问题的关键网络流量如下所示: SUCCESS FA
SUCCESS FAILURE
|----------------------| |----------------------|
| SCANNER | SERVER | | SCANNER | SERVER |
|----------------------| |----------------------|
| | Starts | | Starts | |
| Starts | | | | Starts |
| Scan | Received | | Scan | Received |
| Restarts | | | Restarts | |
--------(Network)------- --------(Network)-------
| SYN | | | SYN | |
| | ACK-123 | | | SYN ACK |
| RST - 123 | | | ACK | |
| SYN | | | | |
| | SYN ACK | | | |
| ACK | | | | |
|----------------------| |----------------------|
| Scan | Received | | Scan | !LOST! |
|----------------------| |----------------------|
如您所见,在成功场景中,扫描程序重新启动后,服务器用ACK响应SYN,扫描程序重置连接,因为它意识到连接不在正确的流中。服务器检测到这一点并优雅地处理它。但是,在故障场景中,服务器会以SYN ACK、scanner ACK响应,并建立新连接
代码没有抱怨任何事情,但是我的TcpLister/TcpClient似乎从来没有收到任何更多的数据,即使在Wireshark中看到的接收和确认数据时也是如此。看起来TcpListener和handler仍然在等待旧的数据连接?我是这个级别的网络编程新手(对C#本身来说也是比较新的),所以如果我遗漏了一些明显的东西,一定要指出
服务器的代码段:
public void Run()
{
而(!关机)
{
shutdown=false;//重置
listenerServer=new TcpListener(IPAddress.Any、scanner.Address.Port);
尝试
{
listenerServer.Start();
TcpClient处理程序=listenerServer.AcceptTcpClient();
while(true)
{
尝试
{
incomingData=null;
dataBuffer=新字节[256];
NetworkStream=handler.GetStream();//此处为块
int i;
while((i=stream.Read(dataBuffer,0,dataBuffer.Length))!=0)
{
incomingData+=Encoding.ASCII.GetString(dataBuffer,0,i);
int startIndex=incomingData.IndexOf(startMarker);
int endIndex=incomingData.IndexOf(endMarker);
如果(开始索引>-1和结束索引>-1)
{
string serialData=incomingData.Substring(startIndex+1,endIndex-startIndex-1);
scanner.ProcessDataChange(serialData);
}
}
}
捕获(IOE异常)
{
//这里处理SocketException。。。
}
最后
{
handler.Close();
}
}
}
捕获(SocketException e)
{
listenerServer.Stop();
listenerServer=null;
}
最后
{
listenerServer.Stop();
listenerServer=null;
}
}
}
这种情况的常见原因是希望保留tcp发送和接收边界。i、 e您发送一个区块,并期望在服务器上接收相同的区块。这种情况不一定会发生,而且由于您不显示代码,我无法判断您是否依赖它用户回答了一个问题,但删除了它,认为它可能与此无关。事实上,这是对这个问题的一个很好的回答,所以我把它转载在这里。最后,我没有听到正在建立的新联系。如果L.B想转告他的答复,我将欣然接受
重新发布L.B.的答案
您只接受一个TcpClient handler=listenerServer.AcceptTcpClient()的连接
当第一个连接关闭时,您将不再接受连接。您应该将其移动到while循环中
编辑
这不是对你问题的直接回答。但我尝试了下面的代码,效果很好。如果你愿意,你可以试试。稍后我将删除此答案
void Run()
{
TcpListener侦听器=新的TcpListener(IPAddress.Any,12345);
listener.Start();
Task.Factory.StartNew(()=>
{
while(true)
{
var client=listener.AcceptTcpClient();
Task.Factory.StartNew(()=>处理程序(客户端),TaskCreationOptions.LongRunning);
}
},TaskCreationOptions.LongRunning);
}
无效处理程序(TcpClient客户端)
{
使用(NetworkStream=client.GetStream())
{
var-dataBuffer=新字节[256];
int i;
while((i=stream.Read(dataBuffer,0,dataBuffer.Length))!=0)
{
//在此处处理数据。。
//var s=Encoding.UTF8.GetString(dataBuffer,0,i);
//控制台。写入;
}
}
}
Gotchya,有趣的想法。在处理代码中添加,如果有帮助的话。因此,您的代码在这方面是可以的,但是您仍然没有正确的aceept/server启动代码