- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我目前正在使用 TcpListener 来处理传入的连接,每个连接都有一个线程来处理通信,然后关闭该单个连接。代码如下所示:
TcpListener listener = new TcpListener(IPAddress.Any, Port);
System.Console.WriteLine("Server Initialized, listening for incoming connections");
listener.Start();
while (listen)
{
// Step 0: Client connection
TcpClient client = listener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleConnection));
clientThread.Start(client.GetStream());
client.Close();
}
listen
变量是一个 bool 值,它是类中的一个字段。现在,当程序关闭时,我希望它停止监听客户端。将 listen 设置为 false
将阻止它接受更多连接,但由于 AcceptTcpClient
是一个阻塞调用,它至少会接受下一个客户端然后退出。有没有什么办法可以迫使它突然爆发并立即停止?在另一个阻塞调用运行时调用 listener.Stop() 有什么影响?
最佳答案
根据代码和我认为是您的设计,您可以使用这两个快速修复方法:
如果您已经从另一个线程启动了这个TcpListener
线程,您可以简单地对该线程调用Abort()
,这将导致一个ThreadAbortException
在阻塞调用中并在堆栈中向上移动。
第二个低成本修复是使用listener.Pending()
方法来实现轮询模型。然后,您可以使用 Thread.Sleep()
等待,然后再查看是否有新连接挂起。一旦你有一个挂起的连接,你调用 AcceptTcpClient()
并释放挂起的连接。代码看起来像这样:
while (listen) {
// Step 0: Client connection
if (!listener.Pending()) {
Thread.Sleep(500); // choose a number (in milliseconds) that makes sense
continue; // skip to next iteration of loop
}
TcpClient client = listener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleConnection));
clientThread.Start(client.GetStream());
client.Close();
}
但是,您真的应该为您的应用程序采用非阻塞方法。在幕后,框架将使用重叠的 I/O 和 I/O 完成端口来实现异步调用的非阻塞 I/O。这也不是很难,只是需要以不同的方式思考您的代码。
基本上,您将使用 BeginAcceptTcpClient()
方法开始您的代码,并跟踪您返回的 IAsyncResult
。您指向一个方法,该方法负责获取 TcpClient
并将其NOT 传递给新线程,而是传递给 ThreadPool.QueueUserWorkerItem
,所以你不会为每个客户端请求启动和关闭一个新线程(注意:如果你有特别长的请求,你可能需要使用你自己的线程池,因为线程池是共享的,如果你独占所有系统实现的应用程序的其他部分的线程可能会被饿死)。一旦监听器方法将新的
TcpClient
启动到它自己的 ThreadPool
请求,它会再次调用 BeginAcceptTcpClient()
并将委托(delegate)指向自身.
实际上,您只是将当前方法分解为 3 个不同的方法,然后这些方法将被不同的部分调用:
引导一切;
作为调用EndAcceptTcpClient()
的目标,启动TcpClient
到它自己的线程,然后再次调用它自己;
处理客户请求并在完成后关闭它。
(注意:您应该将
TcpClient
调用包含在 using(){}
block 中以确保 TcpClient.Dispose ()
或 TcpClient.Close()
方法即使在发生异常时也会被调用。或者,您可以将其放在 finally
block 中 try {} finally {}
block 。)
关于c# - 停止 TcpListener 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/365370/
我有一些代码: protected TcpListener ClientListener; protected TcpClient ClientSocket; protecte
我创建了一个新表单,并在顶部做了: using System; using System.Collections.Generic; using System.ComponentModel; using
我们目前在 Windows 上运行的自行编写的服务器应用程序遇到问题(出现在不同版本上)。服务器监听 TCP 端口,接受连接,交换一些数据,然后再次关闭连接。大约有 100 个客户端不时连接。 有时服
我正在玩一个用 F# 编写的简单网络服务器。正如我所注意到的,如果我在 Firefox 中点击刷新,经过一些尝试,我会收到一个错误页面: The connection was reset The co
为了这个问题的目的,我做了一个 super 简化的例子: using System; using System.Net; using System.Net.Sockets; namespace Loo
我有一个连接到多个客户端的 TcpListener。我可以获得所有已连接客户端的列表吗? 最佳答案 当您在服务器上接受连接时,您可以将客户端放在一个列表中。 TcpListener server =
以下代码与 TcpListener 的 Rust 文档中的代码几乎相同。当代码在 Ubuntu 14.04 上运行时,它不会产生任何错误,但同时它也不起作用! (netstat -an | grep
我有一个 TcpListener,它在关闭时会导致所有进行中的客户端在尝试调用 EndAcceptTcpClient 时抛出以下异常。是否可以使用更优雅的模式来允许所有现有客户端连接在 TcpList
我在 Windows 窗体应用程序中使用 TcpListener;它有一个启动 TcpListener 的“开始”按钮。但是,当我单击开始按钮时,会抛出以下异常: The requested addr
我的窗口上有两个 Button 连接到两个 ICommands: public ICommand Start { get; set; } public ICommand Stop { get; set
我在使用 TCPListener 时遇到问题。我在下面创建了这段代码,它可以与测试应用程序一起使用,但我无法让它接收来自生产环境的连接。在下图中,您可以看到 .44 不断尝试连接,但如控制台窗口输出所
大家好:我正在尝试确保我的 TcpListener 可以正确处理来自客户端的多个请求。我正在尝试在 for 循环内调用多个 BeginSend 方法,发现 Listener 的输出在我得到的响应数量方
我关注了this tutorial设置客户端 -> 服务器基于 TCP 的 Windows 窗体应用程序,其中服务器从客户端接收文件 并且运行良好。结构总结如下: Server uses TcpLis
我有一个通过 tcpListener 进行通信的服务。问题是当用户重新启动服务时 - 抛出“地址已在使用”异常,并且服务在几分钟左右无法启动。 有什么方法可以告诉系统终止旧连接以便我可以打开一个新连接
我如何检测客户端何时与 TcpListener 断开连接? 我的每个客户都在一个单独的线程中处理。 最佳答案 看NetworkStream.Read ,或者取决于您在代码中使用的内容可能是 TCPCl
据我了解,TcpListener一旦您调用Start(),将对连接进行排队.每次调用AcceptTcpClient (或 BeginAcceptTcpClient ),它将从队列中取出一项。 如果我们
你好我想问一下使用这个有什么区别: public TcpListener Listener; public TcpClient Client; Listener = new TcpListener(D
我有一个基于 TCPListener 的 ECHO 服务器应用程序.它接受客户端,读取数据,并返回相同的数据。我使用 async/await 方法开发了它,使用 XXXAsync框架提供的方法。 我已
抱歉发了这么长的帖子。我想使用 TcpListener 来监听端口,处理不同(后台)线程中传入连接请求的繁重工作,然后在准备就绪时将响应发送回客户端。我在MSDN上阅读了大量的代码和示例,并为服务器提
我有以下代码的实例,可以在Debug中或作为独立的Windows应用程序正确执行: TcpListener tcpListener = new TcpListener(IPAddress.Any, 4
我是一名优秀的程序员,十分优秀!