【问题标题】:Reading from 2 sockets in 2 threads causes data loss从 2 个线程中的 2 个套接字读取会导致数据丢失
【发布时间】:2010-09-30 10:49:46
【问题描述】:

我有一个用 Visual Studio 6 编写的多线程 Windows C++ 应用程序。

在应用程序中,有 2 个线程正在运行,每个线程都试图读取不同端口上的 UDP 数据包。如果我用关键部分保护来自套接字的读数,那么所有读取的日期都很好。如果没有这种保护,两个套接字的数据都会丢失。

从套接字读取不是线程安全的吗?我过去写过很多套接字应用程序,但不记得必须使用这种线程保护。

【问题讨论】:

  • 也许您还可以在您的问题中添加一些用于获取数据的 api 调用?

标签: c++ sockets


【解决方案1】:

在两个线程中从一个套接字读取不是线程安全的,您可能不确定哪个调用者首先从底层套接字缓冲区获取数据包。写入套接字是相同的。由于您是从两个不同线程中的两个不同套接字读取数据(并且我假设每个套接字都有自己的线程),所以它应该可以工作。

【讨论】:

    【解决方案2】:

    您确定不是从同一个套接字读取数据吗?在我们的系统中,我们使用的是这样的:2 个绑定的 UDP 套接字 + 2 个线程来读取它们。没有问题,也不需要同步..

    【讨论】:

      【解决方案3】:

      Winsock 不保证是线程安全的。这取决于实施者。看看here

      【讨论】:

        【解决方案4】:

        在应用程序中,有 2 个线程正在运行,每个线程都在尝试读取不同端口上的 UDP 数据包。

        您正在发送/读取多少 UDP 数据?你发送它的速度有多快?您的数据丢失了多少?

        这可能是竞争条件... 不是在两个线程之间,而是在线程和套接字之间!

        我在过去将代码从 Linux 移植到 Windows 时遇到过问题。 Windows 使用(使用)8k 的默认 UDP 缓冲区大小。自然地,我们发送了 12k 突发,即使使用专用读取线程也无法以足够快的速度读取它!

        您可以通过以下方式更改 UDP 缓冲区大小(在 Windows 下):

        int newBufferSize = 128 * 1024;  // 128k
        setsockopt( readSocketFd, SOL_SOCKET, SO_RCVBUF, (char *) & newBufferSize );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-06-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-18
          • 1970-01-01
          • 2014-02-07
          相关资源
          最近更新 更多