【发布时间】: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;
}
如您所见,notifyEntry 和 notifyExit 已被设置为 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发送的那个)。
考虑到这些信息,我想问你:
- 发生这种情况是因为一个线程的
recvfrom也可以捕获另一个请求的响应,因为套接字只实例化了一个绑定套接字? - 如果是,我是否应该实例化多个套接字(例如,每个套接字只能用于一种类型的消息,即一个用于
notifyEntry,一个用于notifyExit)?服务器上的多线程是否仅用于响应并不能解决提到的问题?
【问题讨论】:
标签: c++ multithreading sockets udp