在不关闭套接字的情况下停止阻塞接收

时间:2017-05-05 09:05:10

标签: c multithreading sockets

我遇到了与套接字和多线程相关的设计问题。

请考虑以下事项:

  • 一组网络协议,其底层是使用TCP / IP的套接字层。

  • A"发件人"线程:

    • 执行连接过程(涉及发送和接收数据)

    • 建立连接后,启动"接收器"在后台接收数据的线程。

    • 发送数据。

    • 当应用程序决定退出时,停止接收器线程。

    • 执行断开连接(还涉及发送和接收数据)。

  • A"接收器"在数据交换阶段,即在连接和断开连接之间接收数据的线程。

我的问题是,当发送方线程想要执行断开连接过程时,它首先需要停止接收方线程。因为接收器线程正在执行阻塞接收,所以我知道的阻止它的唯一方法是残酷地关闭套接字。但这样做会阻止我执行干净的断开连接,因为断开连接需要在关闭套接字之前发送和接收数据。

所以我的问题是:是否可以在不关闭套接字的情况下停止阻塞接收,如果是,我该怎么做?或者我是否需要重新设计我的应用程序?

我可以为我的阻止接收添加超时,以便定期检查是否停止接收,但它会感觉不是很敏感,似乎是一种肮脏的方法。

我没有用完整的代码打扰你,因为它按预期工作并具有依赖性。我的接收是使用select()然后是recv()执行的,如下所示:

iRes = select( 0, & fdRead, NULL, NULL, m_nTmout == 0 ? NULL : & tv );
...
iRes = recv( m_hSock, (char *) pBytes, nMaxLen, 0 );

这是Win32代码,但我在Linux上也有类似的东西(Android更具体)。在这两种情况下,我都使用C和C ++。

谢谢。

1 个答案:

答案 0 :(得分:0)

当您使用select()作为阻止操作时,您可以创建pipe()以将命令从发件人传递到接收器

通过将该管道的读取结尾添加到select()读取列表,您可以确定写入该管道的任何命令都会唤醒select()调用。因此接收器将能够处理此命令。