【问题标题】:Questions about multithread UDP Client-Server architecture关于多线程 UDP Client-Server 架构的问题
【发布时间】:2019-06-20 04:31:25
【问题描述】:

我正在练习一些套接字和 UDP 客户端-服务器架构,并参考网络上提供的一些示例,我已经使用 C 实现了一个非常简单的 UDP 服务器,并使用 C++ 实现了一个 UDP 客户端类。
简而言之,当前的实现让服务器监听传入的消息并将相同的数据包发送回客户端。
如果客户端发出顺序请求,它似乎工作正常。
这是一个简短的解释性示例:

#include "UDPClient.h"
int main(int argc, char* argv[]) {
  UDPClient testClient;
  testClient.initSockets(1501, "127.0.0.1", 1500);
  for (int i = 0; i < 10; i++) {
    testClient.notifyEntry();
    testClient.notifyExit();
  }
  return 0;
}

由于客户端实际上应该同时与服务器共享更多信息,因此我测试了启动新线程的相同代码块:

#include <thread>
#include "UDPClient.h"
int main(int argc, char* argv[]) {
  UDPClient testClient;
  std::thread thrdOne, thrdTwo;
  testClient.initSockets(1501, "127.0.0.1", 1500);
  for (int i = 0; i < 10; i++) {
    thrdOne = std::thread(UDPClient::notifyEntry, std::ref(testClient));
    thrdTwo = std::thread(UDPClient::notifyExit, std::ref(testClient));
  }
  return 0;
}

如您所见,notifyEntrynotifyExit 已被设置为 static,目前需要引用类实例才能正常工作。 此外,在它们的函数体中,我还添加了一个小代码块,以检查由于服务器发回相同的内容,发送的消息是否与接收的消息相同。
这是一个解释性示例:

void UDPClient::notifyEntry(UDPClient& inst) {
  char buffer = "E"
  inst.sendPacket(buffer);  // sendto...
  inst.receivePacket(buffer);  // recvfrom...
  if (!(buffer == 'E') ){
    std::string e = "Buffer should be E but it is ";
    e.append(buffer);
    throw UDPClientException(e);
  }
}

使用多线程经常发生上述检查抛出异常,因为缓冲区实际上包含另一个charnotifyExit发送的那个)。

考虑到这些信息,我想问你:

  1. 发生这种情况是因为一个线程的recvfrom 也可以捕获另一个请求的响应,因为套接字只实例化了一个绑定套接字?
  2. 如果是,我是否应该实例化多个套接字(例如,每个套接字只能用于一种类型的消息,即一个用于notifyEntry,一个用于notifyExit)?服务器上的多线程是否仅用于响应并不能解决提到的问题?

【问题讨论】:

    标签: c++ multithreading sockets udp


    【解决方案1】:

    这是因为线程的 recvfrom 也可以捕获 来自另一个请求的响应,被实例化的套接字 只有一个绑定套接字?

    这很有可能——如果您有多个线程在同一个 UDP 套接字上调用 recvfrom(),那么哪个线程接收哪个传入的 UDP 数据包将是不确定/不可预测的。

    如果是,我是否应该实例化多个套接字(例如, 每个消息只能用于一种类型的消息,即一个用于 notifyEntry 和一个用于 notifyExit)?

    是的,我建议让每个线程创建自己的私有 UDP 套接字并将其套接字绑定到自己的单独端口(例如,通过将 0 作为端口号传递给 bind());这样,每个线程可以确保只接收自己的响应,而不会被其他线程的响应混淆。 (请注意,您还需要对服务器进行编码以将其回复发送回recvfrom() 调用报告的 IP 地址和端口,而不是将回复数据包发送回硬编码的端口号)

    服务器上的多线程是否仅用于响应并不能解决问题 还是提到了?

    不,UDP 数据包的正确处理(与否)是一个独立的问题,与服务器是单线程还是多线程无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 2011-05-12
      • 2019-04-12
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多