- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
据我了解,TcpListener
一旦您调用Start()
,将对连接进行排队.每次调用AcceptTcpClient
(或 BeginAcceptTcpClient
),它将从队列中取出一项。
如果我们加载测试 TcpListener
通过一次向它发送 1,000 个连接,队列建立的速度远远超过我们清除它的速度,导致(最终)客户端超时,因为它没有得到响应,因为它的连接仍在队列中。然而,服务器似乎并没有承受太大压力,我们的应用程序没有消耗太多 CPU 时间,机器上其他受监控的资源也没有出汗。感觉我们现在的运行效率不够高。
我们正在调用 BeginAcceptTcpListener
然后马上交给一个ThreadPool
线程实际完成工作,然后调用 BeginAcceptTcpClient
再次。所涉及的工作似乎并没有给机器带来任何压力,它基本上只是 3 秒的 sleep ,然后是字典查找,然后向 TcpClient
写入 100 字节。的流。
这是 TcpListener
我们正在使用的代码:
// Thread signal.
private static ManualResetEvent tcpClientConnected = new ManualResetEvent(false);
public void DoBeginAcceptTcpClient(TcpListener listener)
{
// Set the event to nonsignaled state.
tcpClientConnected.Reset();
listener.BeginAcceptTcpClient(
new AsyncCallback(DoAcceptTcpClientCallback),
listener);
// Wait for signal
tcpClientConnected.WaitOne();
}
public void DoAcceptTcpClientCallback(IAsyncResult ar)
{
// Get the listener that handles the client request, and the TcpClient
TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
if (inProduction)
ThreadPool.QueueUserWorkItem(state => HandleTcpRequest(client, serverCertificate)); // With SSL
else
ThreadPool.QueueUserWorkItem(state => HandleTcpRequest(client)); // Without SSL
// Signal the calling thread to continue.
tcpClientConnected.Set();
}
public void Start()
{
currentHandledRequests = 0;
tcpListener = new TcpListener(IPAddress.Any, 10000);
try
{
tcpListener.Start();
while (true)
DoBeginAcceptTcpClient(tcpListener);
}
catch (SocketException)
{
// The TcpListener is shutting down, exit gracefully
CheckBuffer();
return;
}
}
我假设答案与使用 Sockets
有关而不是 TcpListener
, 或者至少使用 TcpListener.AcceptSocket
,但我想知道我们将如何去做?
我们的一个想法是调用 AcceptTcpClient
并立即 Enqueue
TcpClient
成多个Queue<TcpClient>
之一对象。这样,我们就可以在单独的线程(每个线程一个队列)上轮询这些队列,而不会遇到可能在等待其他线程时阻塞线程的监视器 Dequeue
操作。然后每个队列线程都可以使用 ThreadPool.QueueUserWorkItem
在 ThreadPool
中完成工作线程,然后移动到出列下一个 TcpClient
在它的队列中。您会推荐这种方法,还是我们正在使用的问题 TcpListener
并且再多的快速出队也无法解决这个问题?
最佳答案
我编写了一些直接使用套接字的代码,但我缺乏对 1000 个客户端执行负载测试的方法。您能否尝试测试此代码与您当前的解决方案相比如何?我对结果非常感兴趣,因为我正在构建一个现在也需要接受大量连接的服务器。
static WaitCallback handleTcpRequest = new WaitCallback(HandleTcpRequest);
static void Main()
{
var e = new SocketAsyncEventArgs();
e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed);
var socket = new Socket(
AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 8181));
socket.Listen((int)SocketOptionName.MaxConnections);
socket.AcceptAsync(e);
Console.WriteLine("--ready--");
Console.ReadLine();
socket.Close();
}
static void e_Completed(object sender, SocketAsyncEventArgs e)
{
var socket = (Socket)sender;
ThreadPool.QueueUserWorkItem(handleTcpRequest, e.AcceptSocket);
e.AcceptSocket = null;
socket.AcceptAsync(e);
}
static void HandleTcpRequest(object state)
{
var socket = (Socket)state;
Thread.Sleep(100); // do work
socket.Close();
}
关于c# - TcpListener 排队连接的速度快于我清除它们的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2745401/
我有一些代码: 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
我是一名优秀的程序员,十分优秀!