退出线程阻塞TCP读取C#

时间:2009-08-24 22:35:03

标签: c# multithreading tcp

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

一种方法是启动另一个线程,当线程退出时关闭套接字,这样读取就会退出。是否有更清洁/更好的方法来做到这一点。

5 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:1)

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

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

但如果你选择纯粹的阻止,请按照你的建议使用控制线程。

答案 2 :(得分:1)

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

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

安德鲁

答案 3 :(得分:0)

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

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

答案 4 :(得分:-1)

另一种方法是,当您要关闭它时,从您自己的应用程序中的其他位置向您的侦听套接字发送一个0字节的数据包。

我发现这比从另一个线程关闭coket更简洁,因为如果你关闭它上的套接字,监听线程会抛出异常。