我正在創建一個 udp 客戶端池。服務器將是運行在不同計算機上的一些其他應用程式,并且它們應該從一開始就處于活動狀態。使用可組態檔(在示例中對問題不重要,因此不包括在內)創建一對多客戶端,以便它們以雙向方式連接到這些服務器(一對一關系),發送和接收。
發送可以是同步的,因為它使用小訊息并且在那里阻塞不是問題,但接收必須是異步的,因為回復可以在發送后很晚才到達。
在我只有一個套接字的測驗中,它能夠發送,但它根本沒有接收任何東西。
Q1:問題出在哪里以及如何解決?
Q2:我還想知道std::vector在異步呼叫中使用迭代器是否會在將新連接推送到 vector 時由于其在記憶體中的重新排列而出現問題。這可能是個問題?
Q3:我真的不明白為什么在所有示例中發送方和接收方端點(示例中的端點 1 和端點 2 struct Socket)不同,它們不能相同嗎?
我的代碼是下一個:
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
class Pool
{
struct Socket {
std::string id;
udp::socket socket;
udp::endpoint endpoint1;
udp::endpoint endpoint2;
enum { max_length = 1024 };
std::array<char, max_length> data;
};
public:
void create(const std::string& id, const std::string& host, const std::string& port)
{
udp::resolver resolver(io_context);
sockets.emplace_back(Socket{ id, udp::socket{io_context, udp::v4()}, *resolver.resolve(udp::v4(), host, port).begin() });
receive(id);
}
void send(const std::string& id, const std::string& msg)
{
auto it = std::find_if(sockets.begin(), sockets.end(), [&](auto& socket) { return id == socket.id; });
if (it == sockets.end()) return;
it->data = std::array<char, Socket::max_length>{ 'h', 'e', 'l', 'l', 'o' };
auto bytes = it->socket.send_to(boost::asio::buffer(it->data, 5), it->endpoint1);
}
void receive(const std::string& id)
{
auto it = std::find_if(sockets.begin(), sockets.end(), [&](auto& socket) { return id == socket.id; });
if (it == sockets.end()) return;
it->socket.async_receive_from(
boost::asio::buffer(it->data, Socket::max_length),
it->endpoint2,
[this, id](boost::system::error_code error, std::size_t bytes) {
if (!error && bytes)
bool ok = true;//Call to whatever function
receive(id);
}
);
}
void poll()
{
io_context.poll();
}
private:
boost::asio::io_context io_context;
std::vector<Socket> sockets;
};
int main()
{
Pool clients;
clients.create("ID", "localhost", "55000");
while (true) {
clients.poll();
clients.send("ID", "x");
Sleep(5000);
}
}
uj5u.com熱心網友回復:
Q1:問題出在哪里以及如何解決?
您并沒有真正系結到任何埠,然后您有多個套接字都接收未系結的 udp 資料包。很可能他們只是在競爭,在混亂中迷失了一些東西。
Q2:std::vector 會不會有問題
是的。使用std::deque(穩定的迭代器/參考,只要您只在任一端推送/彈出)。否則,請考慮使用std::list或其他基于節點的容器。
在你的情況下map<id, socket>似乎更直觀。
實際上,map<endpoint, peer>會更直觀。或者......你可以完全沒有同齡人。
Q3:我真的不明白為什么在所有示例中發送方和接收方端點(示例 struct Socket 中的端點 1 和端點 2)不同,它們不能相同嗎?
是的,如果您不關心覆寫您發送到的原始端點,它們可能是“相同的”。
這是我的簡化版。正如其他人所說,在同一端點上有許多 UDP 套接字“偵聽”是不可能/有用的。也就是說,前提是您甚至系結到了一個端點。
所以我的示例使用了一個_socket本地端點:8765。
它可以連接到許多客戶端端點 - 為簡單起見,我選擇用端點本身替換 id 字串。隨意添加map<string, endpoint>一些翻譯。

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/339982.html
