Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TcpListener/TcpClient在某些情况下停止处理数据_C#_.net_Networking_Tcp_Tcpclient - Fatal编程技术网

C# TcpListener/TcpClient在某些情况下停止处理数据

C# TcpListener/TcpClient在某些情况下停止处理数据,c#,.net,networking,tcp,tcpclient,C#,.net,Networking,Tcp,Tcpclient,我有一个问题,根据两个网络设备的启动顺序,我似乎失去了在一端接收数据的能力 该设置是一个用C#(.NET4.0)编写的小型服务器,它监听来自工业扫描仪的特定端口的数据,并通过TCP进行通信。扫描仪与服务器应用程序连接良好,将发送服务器接收和处理的小块数据(序列号)。但是,在扫描仪上重新启动(实际上,循环电源并不能正常关闭其连接)会导致服务器停止处理数据。事件顺序以及导致问题的关键网络流量如下所示: SUCCESS FA

我有一个问题,根据两个网络设备的启动顺序,我似乎失去了在一端接收数据的能力

该设置是一个用C#(.NET4.0)编写的小型服务器,它监听来自工业扫描仪的特定端口的数据,并通过TCP进行通信。扫描仪与服务器应用程序连接良好,将发送服务器接收和处理的小块数据(序列号)。但是,在扫描仪上重新启动(实际上,循环电源并不能正常关闭其连接)会导致服务器停止处理数据。事件顺序以及导致问题的关键网络流量如下所示:

             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启动代码