你好,
如果这不是正确的论坛我很抱歉 - 这是我第一次使用它。
我是尝试编写一个侦听TCP端口的UWP应用程序,并允许最多4个与客户端设备的同时连接。
我有一个我在主UI线程上创建的StreamSocketListener:
public void StartListening(HostName LocalAdapter,ushort LocalPort) { Listener = new StreamSocketListener(); Listener.ConnectionReceived + = Listener_ConnectionReceived; Listener.BindEndpointAsync(LocalAdapter,LocalPort.ToString()); }
当客户端发送连接请求时, Listener_ConnectionReceived正常触发,我将退回的套接字移交给新任务:
private void Listener_ConnectionReceived(StreamSocketListener sender,StreamSocketListenerConnectionReceivedEventArgs args) { 任务t =新任务(StartupTCPSession,args,TaskCreationOptions.LongRunning); t.Start(); } private Action< object> StartupTCPSession =(object ConnectionArgs)=> { StreamSocketListenerConnectionReceivedEventArgs args =(StreamSocketListenerConnectionReceivedEventArgs)ConnectionArgs; TCPSession NewSession = new TCPSession(EIPConnectionMonitor.GetSessionID(),args); NewSession.RunSession(); };TCPSession类:
类TCPSession { 私有StreamSocket Socket; public readonly uint SessionID; private EIPConnectionMonitor Parent; private bool shutdownSession; private Task SessionTask; 私有DataReader Reader; 私有DataWriter Writer; public TCPSession(uint sessionID,StreamSocketListenerConnectionReceivedEventArgs ConnectionInfo) { SessionID = sessionID; Socket = ConnectionInfo.Socket; shutdownSession = false; } public void RunSession() { Reader = new DataReader(Socket.InputStream); Writer = new DataWriter(Socket.OutputStream); while(!shutdownSession) { if(Reader.UnconsumedBufferLength> 0)//如果我在这里设置断点,代码总是停止,我在代码执行时采取 { byte [] RecData = new byte [Reader.UnconsumedBufferLength]; //这里的断点从不命中 Reader.ReadBytes(RecData); //应该读取缓冲区 } else { Task.Delay( 5); } } } public void ShutdownSession() { shutdownSession = true; } }
当我运行此代码时,客户端(PLC)发出连接请求,我的代码通过调用Listener_ConnectionReceived函数看到。
我监视连接使用Wireshark,我可以看到客户端将预期的确切TCP数据包发送到预期的端口,但DataReader从不表示有任何数据可用。
真的很疯狂的事情是这个确切的代码完美无缺地运行了 5天然后停止。我以为我可能在做错线程(或我的硬件失败),所以我写了一个简单的Windows窗体应用程序,使用相同的线程结构,但使用System.Net.Sockets命名空间而不是Windows。 Networking.Sockets命名空间:
使用System; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text; 使用System.Threading.Tasks; 使用System.Net; 使用System.Net.Sockets; 使用System.IO; 命名空间WindowsFormsApp1 { class TCPSession { private TcpListener Listener; private Socket SS; public readonly uint SessionID; private bool shutdownSession; private Task SessionTask; public TCPSession(uint sessionID,Socket socket) { SessionID = sessionID; SS =套接字; } public void RunSession() { while(true) { if(SS.Available> 0) { byte [] NewData = new byte [SS.Available]; //当客户端发送消息时,此处的断点按预期命中 SS.Receive(NewData); } Task.Delay(5); } } } 类EIPConnectionMonitor { private TcpListener Listener; private static UInt32 NextSessionID; private static UInt32 SessionOffset; public EIPConnectionMonitor() { NextSessionID = 0; 随机r = new Random(); SessionOffset =(uint)r.Next(0x10000,0x7fff0000); } public async void ListenForConnections() { int ListenPort = 0xaf12; IPAddress LocalIPAddress = IPAddress.Parse(" 10.57.45.5"); Listener = new TcpListener(LocalIPAddress,ListenPort); Listener.Start(); while(true) { Socket NewSocket = await Listener.AcceptSocketAsync(); 任务t =新任务(StartupTCPSession,NewSocket,TaskCreationOptions.LongRunning); t.Start(); } } 公共静态UInt32 GetSessionID() { NextSessionID + = 1; if(NextSessionID> = 0x1000) NextSessionID = 0x1; return((SessionOffset& 0xffff0000)| NextSessionID); } private Action< object> StartupTCPSession =(对象套接字)=> { TCPSession NewSession = new TCPSession(EIPConnectionMonitor.GetSessionID(),(Socket)socket); NewSession.RunSession(); }; } }我在同一台机器上运行此代码(使用相同的以太网适配器) ),它会像我期望的那样从客户端接收数据。
我假设我意外地改变了导致我的问题的一些项目设置,但我不知道它可能是什么我的UWP应用程序在Package.appxmanifest文件中检查了以下功能:
- 专用网络(客户端和服务器)
- 互联网(客户端和服务器)
我的目标是通用Windows,Windows 10 Fall Creators更新(10.0 build 16299) - 这也是我的最低版本。
我也使用了不同的以太网适配器,但它没有改变结果。
我一直在拔头发3天试图找到告诉我我的问题是什么的论坛帖子,但我找不到解决方案。
非常感谢任何帮助!
解决方案
我也忘了指出我将防火墙保护作为测试禁用,并且没有改变结果。
Hello,
I apologize if this is not the correct forum - this is my first time using one.
I am attempting to write a UWP app that listens on a TCP port, and allows up to 4 simultaneous connections with client devices.
I have a StreamSocketListener that I create on the main UI thread:
public void StartListening(HostName LocalAdapter, ushort LocalPort) { Listener = new StreamSocketListener(); Listener.ConnectionReceived += Listener_ConnectionReceived; Listener.BindEndpointAsync(LocalAdapter, LocalPort.ToString()); }When a client sends a connection request,Listener_ConnectionReceived fires properly and I hand off the returned socket to a new task:
private void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { Task t = new Task(StartupTCPSession, args, TaskCreationOptions.LongRunning); t.Start(); } private Action<object> StartupTCPSession = (object ConnectionArgs) => { StreamSocketListenerConnectionReceivedEventArgs args = (StreamSocketListenerConnectionReceivedEventArgs)ConnectionArgs; TCPSession NewSession = new TCPSession(EIPConnectionMonitor.GetSessionID(), args); NewSession.RunSession(); };The TCPSession Class:
class TCPSession { private StreamSocket Socket; public readonly uint SessionID; private EIPConnectionMonitor Parent; private bool shutdownSession; private Task SessionTask; private DataReader Reader; private DataWriter Writer; public TCPSession(uint sessionID, StreamSocketListenerConnectionReceivedEventArgs ConnectionInfo) { SessionID = sessionID; Socket = ConnectionInfo.Socket; shutdownSession = false; } public void RunSession() { Reader = new DataReader(Socket.InputStream); Writer = new DataWriter(Socket.OutputStream); while (!shutdownSession) { if (Reader.UnconsumedBufferLength>0) //If I set a breakpoint here, the code always stops, which I take as the code is executing { byte[] RecData = new byte[Reader.UnconsumedBufferLength]; //a breakpoint here never hits Reader.ReadBytes(RecData);//should read buffer } else { Task.Delay(5); } } } public void ShutdownSession() { shutdownSession = true; } }
When I run this code, the client (a PLC) issues a connection request, which my code sees via the Listener_ConnectionReceived function being called.
I monitor the connection using Wireshark and I can see that the client sends the exact TCP packet I am expecting, to the expected port, but the DataReader never indicates that there is any data available.
The really crazy thing is that this exact code worked flawlesslyfor 5 days and then stopped. I thought I might be doing something wrong with threading (or that my hardware failed), so I wrote a simple Windows Forms app that uses the same threading structure but uses the System.Net.Sockets namespace instead of the Windows.Networking.Sockets namespace:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace WindowsFormsApp1 { class TCPSession { private TcpListener Listener; private Socket SS; public readonly uint SessionID; private bool shutdownSession; private Task SessionTask; public TCPSession(uint sessionID, Socket socket) { SessionID = sessionID; SS = socket; } public void RunSession() { while (true) { if (SS.Available>0) { byte[] NewData = new byte[SS.Available]; //a breakpoint here hits as expected when client sends message SS.Receive(NewData); } Task.Delay(5); } } } class EIPConnectionMonitor { private TcpListener Listener; private static UInt32 NextSessionID; private static UInt32 SessionOffset; public EIPConnectionMonitor() { NextSessionID = 0; Random r = new Random(); SessionOffset = (uint)r.Next(0x10000, 0x7fff0000); } public async void ListenForConnections() { int ListenPort = 0xaf12; IPAddress LocalIPAddress = IPAddress.Parse("10.57.45.5"); Listener = new TcpListener(LocalIPAddress, ListenPort); Listener.Start(); while (true) { Socket NewSocket = await Listener.AcceptSocketAsync(); Task t = new Task(StartupTCPSession, NewSocket, TaskCreationOptions.LongRunning); t.Start(); } } public static UInt32 GetSessionID() { NextSessionID += 1; if (NextSessionID >= 0x1000) NextSessionID = 0x1; return ((SessionOffset & 0xffff0000) | NextSessionID); } private Action<object> StartupTCPSession = (object socket) => { TCPSession NewSession = new TCPSession(EIPConnectionMonitor.GetSessionID(), (Socket)socket); NewSession.RunSession(); }; } }I run this code on the same machine (using the same Ethernet adapter), and it receives data from the client as I would expect.
I'm assuming I accidently changed some project setting that is causing my problem, but I have no idea what it could be. My UWP app has the following capabilities checked in the Package.appxmanifest file:
- Private Networks (Client & Server)
- Internet (Client & Server)
I am targeting the Universal Windows, Windows 10 Fall Creators update (10.0 build 16299) - that is also my min version.
I've also used a different Ethernet adapter, but it does not change the results.
I've been pulling my hair out for 3 days trying to find forum posts that tell me what my problem is, but I can't find a solution.
Any assistance would be greatly appreciated!
解决方案 I also forgot to point out that I disabled my firewall protection as a test and it did not change the results.更多推荐
StreamSocket.InputStream始终为空
发布评论