这是我上一个问题here的扩展,其中包含" 最小可行示例"代码。
我开发了一个UDPClient& UDPServer应用程序如下。这些应用与boost official udp client& boost official udp server:
UDPClient.cpp
#include <iostream>
#include <algorithm>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
struct Person {
char name[1024];
int age;
};
int main(int argc, char* argv[]) {
// Turn this variable TRUE on to send structs of "Person"
bool send_structs = false;
try {
if (argc != 2) {
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
udp::resolver resolver(io_service);
udp::resolver::query query(udp::v4(), argv[1], "7123");
udp::endpoint receiver_endpoint = *resolver.resolve(query);
udp::socket socket(io_service);
socket.open(udp::v4());
for (;;) {
if (send_structs == true) {
// Send structs
Person send_data = { "something_from_client", 123 };
boost::system::error_code ignored_error;
socket.send_to(boost::asio::buffer(&send_data, sizeof(send_data)), receiver_endpoint, 0, ignored_error);
udp::endpoint sender_endpoint;
Person receive_data;
std::size_t len = socket.receive_from(boost::asio::buffer(&receive_data, sizeof(receive_data)), sender_endpoint);
std::cout << "After receiving at client header is " << receive_data.name << std::endl;
std::cout << "After receiving at client version is " << receive_data.age << std::endl;
}
else {
// Send & receive char vectors
std::vector<unsigned char> send_data(1024);
std::string str = "Hello from Client";
std::copy (str.begin(),str.begin(), send_data.begin());
boost::system::error_code ignored_error;
std::cout << "Before sending vector length is " << send_data.size() << std::endl;
socket.send_to(boost::asio::buffer(send_data.data(), send_data.size()), receiver_endpoint, 0, ignored_error);
udp::endpoint sender_endpoint;
std::vector<unsigned char> receive_data;
receive_data.resize(1024);
std::size_t bytes_rec = socket.receive_from(boost::asio::buffer(receive_data), sender_endpoint);
std::cout << "After receiving at client vector size is " << receive_data.size() << std::endl;
std::cout << "Received bytes at client are " << bytes_rec << std::endl;
}
}
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
UDPServer.cpp
#include <iostream>
#include <algorithm>
#include <boost/asio.hpp>
using boost::asio::ip::udp;
struct Person {
char name[1024];
int age;
};
int main() {
// Turn this variable TRUE on to send structs of "Person"
bool send_structs = false;
try {
boost::asio::io_service io_service;
udp::socket socket(io_service, udp::endpoint(udp::v4(), 7123));
for (;;) {
udp::endpoint remote_endpoint;
if (send_structs == true) {
// Send structs
boost::system::error_code error;
Person receive_data;
size_t len = socket.receive_from(boost::asio::buffer(&receive_data, sizeof(receive_data)), remote_endpoint, 0, error);
std::cout << "After receiving at server header is " << receive_data.name << std::endl;
std::cout << "After receiving at server version is " << receive_data.age << std::endl;
if (error && error != boost::asio::error::message_size)
throw boost::system::system_error(error);
boost::system::error_code ignored_error;
Person send_data = { "something_from_server", 456 };
socket.send_to(boost::asio::buffer(&send_data, sizeof(send_data)), remote_endpoint, 0, ignored_error);
}
else {
// Send & receive char vectors
boost::system::error_code error;
std::vector<unsigned char> receive_data;
receive_data.resize(1024);
std::size_t bytes_rec = socket.receive_from(boost::asio::buffer(receive_data), remote_endpoint, 0, error);
std::cout << "Bytes received at server are " << bytes_rec << std::endl;
std::cout << "After receiving at server vector length is " << receive_data.size() << std::endl;
if (error && error != boost::asio::error::message_size)
throw boost::system::system_error(error);
boost::system::error_code ignored_error;
std::vector<unsigned char> send_data(1024);
std::string str = "Hello from Server";
std::copy (str.begin(),str.begin(), send_data.begin());
std::cout << "Before sending vector length is " << send_data.size() << std::endl;
std::size_t bytes_sent = socket.send_to(boost::asio::buffer(send_data.data(), send_data.size()), remote_endpoint, 0, ignored_error);
std::cout << "Bytes sent from server are " << bytes_sent << std::endl;
}
}
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
我正在使用编译命令在clang OSX上构建应用程序:
clang++ -std=c++14 -lboost_system UDPClient.cpp -o UDPClient
clang++ -std=c++14 -lboost_system UDPServer.cpp -o UDPServer
在控制台上运行 这样的应用程序。首先在客户端启动之前运行服务器:
./UDPServer
./UDPClient <host_ip>
以下是问题:
当我通过在两侧设置布尔标志send_structs
作为true
发送结构时,它可以很好地发送结构。但是,当我将send_structs
设置为双方都是假的时候。尝试使用相同的技术发送std::vector<unsigned char>
,奇怪的是它不起作用。
那么,如何使用boost asio在UDP套接字上发送std::vector
unsigned char
服务器应用日志快照:
After receiving at server vector length is 0
Before sending vector length is 1024
Bytes sent from server are 1024
Bytes received at server are 0
After receiving at server vector length is 0
Before sending vector length is 1024
Bytes sent from server are 1024
Bytes received at server are 0
After receiving at server vector length is 0
客户端应用日志快照:
Before sending vector length is 1024
After receiving at client vector size is 0
Received bytes at client are 0
Before sending vector length is 1024
After receiving at client vector size is 0
如您所见,收到矢量长度后为零!!
PS:我还注意到,在发送结构时,当我首先启动服务器时,它会一直等到客户端打开套接字。 但是,当发送向量时,服务器只是盲目地继续循环发送。这是我的代码或预期行为中的错误吗? (次要问题)
答案 0 :(得分:1)
如果要接收矢量,则必须调整缓冲区大小以指示您希望接收多少。这正是这个答案中发生的事情:boost asio write/read vector
现在,这个:
std::vector<unsigned char> receive_data;
std::size_t bytes_rec = socket.receive_from(boost::asio::buffer(receive_data), sender_endpoint);
要求接收0个字节(因为接收缓冲区的大小为0)。
您可能知道预期的数据报大小。否则,您可以简单地过度标注缓冲区,因为收到的bytes_rec
将告诉您已收到多少元素。