ZLMediaKit / ZLToolKit

一个基于C++11的轻量级网络框架,基于线程池技术可以实现大并发网络IO
MIT License
1.88k stars 572 forks source link

UdpServer clone策略问题 #198

Closed kongxa closed 6 months ago

kongxa commented 6 months ago

1、当前代码中存在两种clone策略,通过条件编译采用多socket监听同一本地ip:port方式。这种方式在Windows上是否存在问题,从Windows实际编码测试看,只有先监听的文件描述符可以正常接收数据,后续监听的文件描述符接收不到任何数据 2、从程序注释看“某些系统上线程漂移问题更严重”,具体能说明是哪些系统吗?为什么会这样?

for (auto &pr: _cloned_server) {
        // 启动子Server
#if 0
        pr.second->_socket->cloneSocket(*_socket);
#else
        // 实验发现cloneSocket方式虽然可以节省fd资源,但是在某些系统上线程漂移问题更严重
        pr.second->_socket->bindUdpSock(_socket->get_local_port(), _socket->get_local_ip());
#endif
 }
xia-chu commented 6 months ago

实测好像是Windows系统 记得不是太清楚了 你可以测试下

kongxa commented 6 months ago

可是这样监听同样的本地地址和端口,windows上也只有最先监听的UdpServer可以接收数据,其余UdpServer接收不到数据,windows下还有必要clone多个服务吗?

xia-chu commented 6 months ago

可是这样监听同样的本地地址和端口,windows上也只有最先监听的UdpServer可以接收数据,其余UdpServer接收不到数据

是这样吗? 有出处吗?Windows上确实存在udp接受fd跟预期的不太一致,也就是udp connect后,也不能提高优先级。 不过我再Windows上很少开发测试,情况也不是很了解

kongxa commented 6 months ago

从网上找了些资料,而且我自己写代码验证过了,确实之后先bind的才能收到数据,后面的收不到。但是从msdn上确实没有找到对应的描述。 1、https://learn.microsoft.com/zh-cn/windows-hardware/drivers/network/sharing-transport-addresses 2、https://learn.microsoft.com/zh-cn/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse#using-so_reuseaddr 3、https://www.51cto.com/article/475726.html?u_atoken=645aa49e-53d2-447b-8ac5-4f206ed91f9a&u_asession=01D16dNfBF7BoYDnW67T4DA6_lK43EBKwZQOZWuIv7sQ319B61KGkCFg_htuI_EWnJzx77841jI3KCHWdiHlqxldsq8AL43dpOnCClYrgFm6o&u_asig=05eSL-lwKzeCrURTCAYI4JXu-PMSdtR24gXvBYaPdN5T1ZtmV5pwS5JQFKJQKHVHagOKtRBh4-BCRcZcHKZltvndy9PN0902Eclpw6nLY0crKEaEYzQ_H_ZI5vEaLYvhxWj-PJOZ6e00u5vq5ZUV9Czdzvc0kteP4qsfvw0wFtqk40ZxRVxAyj3UAmH6lZG5QFksmHjM0JOodanL5-M1Qs1RM_5Pm7Oi_ihmOZr3AkzI0qgrOOmwFNe_J_VN0X6BjzLqwGsqtEBnRiJIjcCiDKouKTtDjy1l_F_qZ5clp5NSbUpLHxH1iRKZmnjAu0Zefw&u_aref=gjOeO%2Bar7tXA%2FP4KIElTA%2FvDHPg%3D

xia-chu commented 6 months ago

那Windows下 udp多线程收udp head包的机制是不生效的 不过只要udp connect能提高fd优先级 那么也可以 只要大部分流量走udp connect后的fd就不影响性能 但是这点好像在Windows以及比较老的linux内核也不能保证

xia-chu commented 6 months ago

你可以测试下cloneSocket方案 看看会不会导致抢占 udp connect fd的事件

xia-chu commented 6 months ago

现在zlm的udp server的fd分为两种,一种是server类型的 就是类似于tcp的listen fd,用于accept用, 只接受udp第一个头包,接受后创建另外一种的peer udp fd并connect peer 地址,我们期望后续peer地址的流量都走这个peer fd。

xia-chu commented 6 months ago

但是如果用cloneSocket方案 这个udp server fd就会绑定到所有poller线程监听,可能会导致抢占peer fd的事件

xia-chu commented 6 months ago

如果用bindUdpSock方案 就是新增udp server fd监听同一个端口,但是只绑定其他poller线程,每个poller线程对应一个fd。 这种方案实测抢占peer fd事件的概率比较小

xia-chu commented 6 months ago

反正Windows上有些特性无法开启 程序只能保证逻辑的正确性 至于性能 将就用吧 反正没几个人用Windows做服务端生产环境的

xia-chu commented 6 months ago

说了这么多 不给个star支持下?😁

kongxa commented 6 months ago

是的 我就是在阅读代码的时候看到这个地方有点疑惑,担心自己忽略的什么。看样子windows在使用UDP的时候,确实和linux不太一致