使用相同的 udp 套接字进行异步接收/发送

2024-03-23

我在 udp 服务器中使用相同的套接字,以便在某个端口上接收来自客户端的数据,然后在处理请求后使用 ip::ud::socket ::async_send_to 响应客户端

接收也是与 async_receive_from 异步完成的。套接字使用相同的ioService(毕竟是相同的套接字) 文档没有明确说明同一 udp 套接字是否可以同时从客户端 A 接收数据报(以异步方式),并可能同时向客户端 B 发送另一个数据报(异步发送) 我怀疑这可能会导致问题。我最终使用相同的套接字进行回复,因为在回复另一个客户端时无法将另一个套接字绑定到同一服务器端口。

如何将另一个套接字绑定到同一服务器端口?

EDIT。我尝试使用以下命令将第二个 udp 套接字绑定到同一个 UDP 端口:

socket(ioService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port))

当我第一次这样做时(绑定服务器“接收”套接字),这是可以的,但第二次尝试创建另一个套接字,就像它在绑定时报告错误(asio 抛出异常)


UDP 套接字可以同时从一个远程端点接收数据并将其发送到另一远程端点。然而,根据 Boost.Asio线程和 Boost.Asio http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/overview/core/threads.html根据文档,对单个对象进行并发调用通常是不安全的。

因此,这是安全的:


 thread_1                             | thread_2
--------------------------------------+---------------------------------------
socket.async_receive_from( ... );     |
socket.async_send_to( ... );          |  

这是安全的:


 thread_1                             | thread_2
--------------------------------------+---------------------------------------
socket.async_receive_from( ... );     |
                                      | socket.async_send_to( ... );  

但这被指定为不安全:


 thread_1                             | thread_2
--------------------------------------+---------------------------------------
socket.async_receive_from( ... );     | socket.async_send_to( ... );
                                      |  

请注意,某些功能,例如boost::asio::async_read http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/async_read/overload1.html, are a 组合操作,并且有额外的线程安全限制。


如果以下任一条件为真,则不需要发生额外的同步,因为流程将是隐式同步的:

  • 所有套接字调用都发生在处理程序中,并且io_service::run()仅从单个线程调用。
  • async_receive_from and async_send_to仅在同一异步操作链中调用。例如,ReadHandler传递给async_receive_from调用async_send_to,以及WriteHandler传递给async_send_to调用async_receive_from.

    void read()
    {
      socket.async_receive_from( ..., handle_read );  --.
    }                                                   |
        .-----------------------------------------------'
        |      .----------------------------------------.
        V      V                                        |
    void handle_read( ... )                             |
    {                                                   |
      socket.async_send_to( ..., handle_write );  --.   |
    }                                               |   |
        .-------------------------------------------'   |
        |                                               |
        V                                               |
    void handle_write( ... )                            |
    {                                                   |
      socket.async_receive_from( ..., handle_read );  --'
    }
    

另一方面,如果有多个线程可能并发调用套接字,则需要进行同步。考虑通过调用函数和处理程序来执行同步升压::asio::io_service::strand http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service__strand.html,或者使用其他同步机制,例如Boost.Thread的mutex http://www.boost.org/doc/libs/1_51_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.mutex.


除了线程安全之外,还必须考虑对象生存期的管理。如果服务器需要同时处理多个请求,那么要小心该请求的所有权buffer and endpoint对于每个请求->处理->响应链。每async_receive_from http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/basic_datagram_socket/async_receive_from/overload1.html的文档中,调用者保留两者的所有权buffer and endpoint。因此,通过以下方式管理对象的生命周期可能会更容易升压::shared_ptr http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/smart_ptr.htm。否则,如果链足够快,不需要并发链,那么它就简化了管理,允许相同的buffer and endpoint根据请求使用。


最后,socket_base::reuse_address http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/socket_base/reuse_address.html类允许将套接字绑定到已在使用的地址。但是,我认为这不是一个适用的解决方案,因为它通常使用:

  • 对于 TCP 来说,允许进程重新启动并侦听同一端口,即使该端口位于同一端口TIME_WAIT state.
  • 对于UDP来说,允许多个进程绑定到同一个端口,允许每个进程通过组播接收和广播。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用相同的 udp 套接字进行异步接收/发送 的相关文章

随机推荐

  • 如何通过文件将参数传递给tortoiseproc.exe?

    我正在使用 java 中的 Runtime getRuntime exec 以编程方式生成要提交到 cmd exe 的命令 该命令是tortoiseproc忽略形式的命令 tortoiseproc command ignore path f
  • 在 Python 3 中创建抽象属性会导致 AttributeError

    如何在 python 中创建抽象属性 import abc class MyClass abc ABC abc abstractmethod property def foo self pass 结果出现错误AttributeError a
  • 如何将 PostgreSQL 数据库迁移到 SQLServer 数据库?

    我有一个 PostgreSQL 数据库 我想将其迁移到 SQL Server 架构和数据 我很穷 所以我不想付任何钱 我也很懒 所以不想做太多工作 目前我正在逐个桌子做这个 大约有100个桌子要做 这是极其乏味的 有什么技巧可以达到我想要的
  • JavaScript 支持的网站的自动导航

    我需要在 Python 中自动导航 JavaScript 支持的网站 以便我可以抓取一些内容 我碰到鸡足 http groups csail mit edu uid chickenfoot quickstart html 这是一个 Fire
  • 使用 CakePHP 分页助手进行引导分页

    我正在尝试让 CakePHP 的分页助手与 bootstrap 很好地配合 也就是说 我希望我的分页元素看起来像 bootstrap 的 但由 CakePHP 生成 目前我的视图页面上有这个 它产生以下标记 div class pagina
  • 在 C 中使用 mmap 读取二进制文件时出现段错误

    我正在尝试在 C 中使用 mmap 只是为了看看它到底是如何工作的 目前我尝试使用 mmap 逐字节读取二进制文件 我的代码是这样的 include
  • Android - 在 invalidate() 上重绘后监听器

    在我要求视图失效后 我希望在视图完成重绘后收到通知 正如中所述这个答案 https stackoverflow com a 5073130 72746 the invalidate 方法不调用视图的onDraw UI 立即执行 但会在消息队
  • 索引 null 变量时未引发 php 未定义索引通知

    我很想知道 PHP 中的以下行为是否是有意的 而且 如果有意的话 通过创建索引来从空变量初始化数组被认为是可以接受的 如第一个代码片段中所做的那样 error reporting E ALL arr null echo arr blah n
  • 我可以制作两栏水晶报表吗?

    我有一份报告 其中包含该月每一天的一个详细信息行 我想在左侧的一个 组列 中显示第 1 到 15 天的信息 在右侧显示其他天的信息 每个 组列 都包含四个信息列 我可以通过拆分报告数据库查询列来手动完成此操作 但我真的希望有一种更优雅的方法
  • Objective C 距离字符串格式化程序

    我有一个距离作为浮动 我正在寻找一种方法来为人类读者很好地格式化它 理想情况下 我希望随着它变大 它从 m 变为 km 并很好地舍入数字 转换成里程将是一个额外的好处 我确信很多人都需要其中之一 我希望有一些代码在某个地方 这是我想要的格式
  • 在init块中初始化变量并在kotlin中为该变量定义一个setter

    我想写这段代码 但它不起作用 private var a Int set value field a Code init a 2 我必须在声明变量时对其进行初始化 为什么会发生这种情况 我该如何解决 您的属性有一个自定义设置器 当您调用时a
  • Magento:在一页结账中显示审核步骤

    我一生都无法弄清楚这一点 我想立即在 Magento 的一页结账上显示订单审核步骤 处理订单之前的最后一步 有什么建议么 谢谢大家 如果你查看 onepage phtml 的底部 你会看到 accordion openSection opc
  • 如何通过 Scala 中的 Play Framework 2.5 流式传输压缩文件(即时)?

    我想流式传输一些文件并即时压缩它们 以便用户可以将多个文件下载到一个压缩文件中 而无需向本地磁盘写入任何内容 但是 我当前的实现将所有内容保存在内存中 并且不适用于大文件 有什么办法可以解决吗 我正在研究这个实现 https gist gi
  • FCM 数据消息无法在 Firefox 中加载

    我正在使用 Web FCM 进行云消息传递 当我发送一个通知有了标题和正文 Firefox 和 Chrome 都会显示通知并且工作正常 但是当我尝试发送 FCM 时Data消息 Firefox 不接收和记录消息 我正在使用一个HTTPS安全
  • 如何鼓励 MediaWiki 上的非匿名编辑?

    Problem 在工作中我们有一个部门维基 运行媒体维基 http www mediawiki org 不幸的是有几个 人们在没有登录的情况下进行编辑 这使得追踪变得非常困难 向下编辑询问有关内容的问题 有两种策略可以改善这一点 鼓励登录编
  • Jquery .delay().fadeOut 取消/清除队列..可能吗?如何?

    我需要一些帮助 是否可以取消链接延迟 Mn Base TopBox show function timedur element fadeIn delay timedur fadeOut Mn Base TopBox cancelFadeou
  • Android:ScrollView 不滚动

    我正在尝试创建一个布局 其中包含标题 标题下方的横幅 然后横幅下有几个 ListView 我希望除标题之外的整个屏幕都可以滚动 现在我知道 ListView 不会在 ScrollView 中滚动 因此我将 ListView 的高度设置得足够
  • wpf mvvm ..访问视图模型中的视图元素

    我正处于学习 wpf mvvm 的阶段 因为我知道在 vm 中我们声明命令并将它们绑定到视图元素的事件 而不是在代码隐藏文件中执行此操作 我没有得到的是 我们将如何访问视图元素和事件参数 您的 ViewModel 不会直接访问视图中的元素
  • Luis 的 Azure 密钥不可用

    我正在尝试发布我的 LUIS 应用程序的暂存版本 我已在 Azure 澳大利亚东部设置了认知服务应用程序 并且可以在 Azure 门户中看到密钥 然而在 AU Luis 门户网站中https au luis ai https au luis
  • 使用相同的 udp 套接字进行异步接收/发送

    我在 udp 服务器中使用相同的套接字 以便在某个端口上接收来自客户端的数据 然后在处理请求后使用 ip ud socket async send to 响应客户端 接收也是与 async receive from 异步完成的 套接字使用相