gpt4 book ai didi

c++ - 关于多线程UDP Client-Server架构的问题

转载 作者:行者123 更新时间:2023-11-28 04:25:40 27 4
gpt4 key购买 nike

我正在练习一些套接字和 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);
}
}

使用多线程经常会发生上面提到的检查抛出异常,因为缓冲区实际上包含另一个char(notifyExit发送的那个)。

考虑到这些信息,请问您:

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

最佳答案

this happens because the recvfrom of a thread can catch also the response of a request from another one, being the socket instantiated only a single bound socket?

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

if yes, should I instantiate more than a single socket (for instance, each one usable for only a single type of messages, that is one for notifyEntry and one for notifyExit)?

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

Does multithreading on server for response only not solve the issue mentioned anyway?

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

关于c++ - 关于多线程UDP Client-Server架构的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54380525/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com