TcpListener的Pending方法返回错误值

3

我在服务器端有以下代码:

// Bind to a specific local port number (SERVER_PORT) and any local IP address.
m_tlServer = new TcpListener(IPAddress.Any, SERVER_PORT);

// Start listening for connection attempts.
m_tlServer.Start();

// Start accepting new clients.
// Sleep until a new client(s) will try to connect to the server.
while (!m_bStopThread)
{
    if (!m_tlServer.Pending())
    {
        // Sleep and try again.
        Thread.Sleep(LISTENING_SLEEP_TIME);
        continue;
    }
    else
    {
        // Accept a new client in a new thread. 
        Thread newthread = new Thread(new ThreadStart(HandleNewConnection)); 
        newthread.Start();
    }
}

我的问题是当客户端尝试连接服务器时,方法Pending会多次返回true(通常是4次),并且会创建多个线程。我尝试用使用AcceptTcpClient方法的循环替换该while循环(不知道是否有任何连接尝试),这样可以正常工作。因此,我认为问题是由Pending方法引起的。有人能帮我吗?谢谢,Ofer。
1个回答

2

使用AcceptTcpClient而不是Pending,就能使它正常工作。

为什么你现在的做法会出现以下步骤:

  1. 监听线程看到Pending == true
  2. 启动接受线程
  3. 监听线程看到Pending == true
  4. 启动接受线程
  5. 监听线程看到Pending == true
  6. 启动接受线程
  7. 第一个接受线程开始运行
  8. 监听线程看到Pending == false

简言之,这并不是因为你启动了一个线程,就会立即执行一些随机的指令。线程的目的正是:稍后执行。

如果你想要有一种停止监听进程的方法,可以使用WaitHandles

// In your class somewhere stopEvent is a ManualResetEvent

while(true)
{

    var asyncResult = listener.BeginAcceptTcpClient(null, null);

    var waitHandles = new [] { stopEvent, asyncResult.AsyncWaitHandle };

    var waitResult = WaitHandle.WaitAny(waitHandles);

    if (waitResult == 0) return;

    var client = EndAcceptTcpClient(asyncResult);
    // Create thread to speak with this client

}

您想要停止线程的方法只需要stopEvent.Set()

1
@Fuex:事实上是真的,但池化是一个坏主意,应该尽一切可能避免使用。我们不需要更多糟糕编程的软件占用我们计算机的处理器。有一种高效、更快、更简单的替代方案,为什么要使用更差的解决方案呢? - Julien Roncaglia
@Fuex 如果要终止'accept', 你也可以使用回调并在开始时检查一些m_stop变量,但框架在这种情况下的操作基本上是在一个线程池线程中执行我编写的代码并调用您的回调。在像这样的简单情况下,结果是相同的。但真正的异步IO更加强大,因为同一线程可以等待新客户端、等待所有客户端上的新数据包到达以及等待数据包被发送...(然后你运行JavaScript而不是C#,并称其为node.js) - Julien Roncaglia
2
应该有一个“与幽灵交谈”的徽章。 - Julien Roncaglia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接