【问题标题】:Exiting a thread blocking on TCP read in C#在 C# 中退出 TCP 读取的线程阻塞
【发布时间】:2010-11-22 10:43:16
【问题描述】:

我的服务器/客户端启动一个新线程“readerThread()”来读取传入的 tcp 流量。该线程在 read() 上阻塞。我怎样才能退出这个 readerThread()。

一种方法是启动另一个线程,该线程在要退出线程时关闭套接字,以便退出读取。有没有更清洁/更好的方法。

【问题讨论】:

    标签: c# multithreading tcp


    【解决方案1】:

    如果您使用阻塞式 read() 命令,您应该几乎总是有另一个控制线程负责关闭它并清理套接字。

    不过,通常情况下,我会使用一个 select() 调用,该调用在 1 秒左右后超时来测试是否有要读取的数据,并且每个超时周期都会检查另一个线程是否设置了关闭状态标志。

    但如果您使用纯阻塞,请按照您的建议使用控制线程。

    【讨论】:

    • 喜欢 select() 在 unix 网络编程中超时?你有任何用c#做的例子吗
    • 或者,只要使用非阻塞 I/O 并在函数调用返回时检查状态。
    • 如果是简单的程序,Matthew 的建议是个好主意。不过,我目前在 C# 中没有任何示例。但是,是的,就像 select()。在 C# 中甚至应该有一个选择调用。 . . select 不仅是一个 unix 命令,它也在 windows 中。
    • select() 等效项:System.Net.Sockets.Socket.Select。更好的选择是 System.Net.Sockets.Socket.Poll。
    【解决方案2】:

    我会使用 Asnyncronous Socket 通信。我写了一篇文章,在我的博客上演示了这一点。你可以在这里阅读:

    http://www.andrewrea.co.uk/blog/2009/06/09/Part1SocketProgrammingWithCJAVACAndActionScript30EstablishingABaseConnectionAndCommunicationWithCServerAndAS3.aspx

    安德鲁

    【讨论】:

      【解决方案3】:

      另一种方法是当你想关闭它时,从你自己的应用程序的其他地方向你的监听套接字发送一个 0 字节的数据包。

      我发现这比从另一个线程关闭 coket 稍微干净一些,因为如果关闭其上的套接字,侦听线程将引发异常。

      【讨论】:

      • TCP 中没有 0 字节数据包这样的东西,你不能向监听套接字发送任何东西。
      【解决方案4】:

      我有点困惑你到底在做什么:.NET 中的 Socket 类没有 read() 方法。

      我的建议是创建第二个套接字,它正在侦听特定端口,并将线程块放在Socket.Select 中。连接到第二个套接字应该被视为关闭请求(可能在适当的身份验证之后,例如通过该套接字发送应用程序密码)。

      【讨论】:

        【解决方案5】:

        我误解了这个问题。这是我认为你应该做的。

        • 如果你在父线程中创建了套接字,并且只使用新线程来读取传入的数据,那么我建议调用 Socket.Shutdown()。这样 Receive 方法将返回 0(不读取字节),您可以退出线程的方法。关闭将禁用发送/接收,但如果缓冲区中有任何数据等待发送/接收,它将确保在关闭套接字之前发送/接收它。如果您在接收时阻塞套接字时调用关闭,则接收方法将返回 0,但它会抛出套接字异常,套接字错误代码 = Shutdown(或 10058)。所以准备好抓住它并处理它。

        • 如果您在新线程中创建套接字,并且它接受新连接(Socket.Listen() 和 Socket.Accept),那么您可以从父线程连接到该套接字并发送 0 个字节。当 Receive 方法返回 0 字节时,您可以退出新线程。

        • 如果您在新线程中创建套接字,并且它只能是一个客户端(与其他套接字连接),那么这根本不是一个好方法。您可能必须中止线程(不推荐),除非您将服务器配置为在您希望客户端套接字关闭时发送 0 字节,但这样您的客户端应用程序将依赖服务器来关闭套接字。

        【讨论】:

          猜你喜欢
          • 2013-02-27
          • 1970-01-01
          • 2023-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-15
          • 1970-01-01
          • 2011-10-30
          相关资源
          最近更新 更多