您好我一直在尝试实现一个简单的服务器/客户端应用程序通过UDP套接字进行通信并了解UDP如何使用boost库工作,我的问题是async_receive没有被调用或者没有完成以便跳转到处理
UDP服务器:
#include "udp_server.h"
udp_server::udp_server(boost::asio::io_service& io_service, string bind_address, uint16_t bind_port)
: socket_(io_service)
{
cout << "udp_server constructor start" << endl;
boost::shared_ptr<boost::asio::io_service::work> work(
new boost::asio::io_service::work(io_service));
for(int x=0; x<5; ++x)
{
worker_threads.create_thread(boost::bind(&udp_server::WorkerThread, this , boost::ref(io_service)));
}
boost::system::error_code myError;
boost::asio::ip::address IP;
IP = boost::asio::ip::address::from_string(bind_address, myError);
local_udppoint_.address(IP);
cout << "IP Address: " << local_udppoint_.address().to_string() << endl;
local_udppoint_.port(bind_port);
cout << "Port: " << local_udppoint_.port() << endl;
socket_.open(local_udppoint_.protocol(), myError);
std::cout << "Open - " << myError.message() << std::endl;
socket_.bind( local_udppoint_, myError );
std::cout << "Bind - " << myError.message() << std::endl;
udp::endpoint sender_endpoint_;
struct test *request = (struct test *) malloc (sizeof(struct test));
socket_.async_receive_from(
boost::asio::buffer(&request, sizeof(request->type)), sender_endpoint_,
boost::bind(&udp_server::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
cout << "udp_server constructor end" << endl;
}
void udp_server::WorkerThread(io_service &io_service_)
{
std::cout << "Thread Start\n";
io_service_.run();
std::cout << "Thread Finish\n";
}
void udp_server::handle_receive_from(const boost::system::error_code& err, size_t bytes_recvd)
{
cout << "udp_server::handle_receive_from enters?" << endl;
if(!err)
{
cout << "no message" << endl;
}
else
{
cout << err.message() << endl;
}
if (!err && bytes_recvd > 0)
{
cout << "All good" << endl;
}
else
{
cout << err.message() << "2" << endl;
}
}
udp_server::~udp_server(void)
{
//io_service.stop();
worker_threads.join_all();
cout << "udp_server::destructor" << endl;
}
服务器主要:
#include "udp_server.h"
int main()
{
try
{
boost::asio::io_service io_service;
//boost::asio::io_service::work work( io_service);
udp_server s(io_service, "127.0.0.1", 4000);
//io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
string a;
cin >> a;
return 0;
}
UDP客户端:
#include "udp_client.h"
udp_client::udp_client(boost::asio::io_service& io_service, string send_address, uint16_t send_port)
: io_service_(io_service), socket_(io_service)
{
cout << "udp_client::constructor_start" << endl;
boost::system::error_code myError;
boost::asio::ip::address IP;
IP = boost::asio::ip::address::from_string(send_address, myError);
remote_endpoint_.address(IP);
cout << "IP Address: " << remote_endpoint_.address().to_string() << endl;
remote_endpoint_.port(send_port);
cout << "Port: " << remote_endpoint_.port() << endl;
struct test *request = (struct test *) malloc (sizeof(struct test));
request->type = START_STORAGE;
socket_.async_send_to(boost::asio::buffer(&request, sizeof(request->type)), remote_endpoint_,
boost::bind(&udp_client::start_handler, this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
cout << "udp_client::constructor_end" << endl;
}
void
udp_client::start_handler(const boost::system::error_code&, std::size_t)
{
cout << "udp_client::start_handler()" << endl;
}
udp_client::~udp_client(void)
{
}
客户的主要内容:
#include "udp_client.h"
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
udp_client client(io_service, "127.0.0.1", 4000);
io_service.run ();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
string a;
cin >> a;
return 0;
}
正如您在客户端调用async_send_to下面的输出中所看到的那样,正在打印处理程序上的消息但在服务器端没有任何反应
UDP服务器控制台输出:
udp_server constructor star
Thread Start
Thread Start
Thread Start
Thread Start
Thread Start
IP Address: 127.0.0.1
Port: 4000
Open - The operation completed successfully
Bind - The operation completed successfullyudp_server constructor end
_
UDP客户端控制台:
udp_client::constructor_start
IP Address: 127.0.0.1
Port: 4000
udp_client::constructor_end
udp_client::start_handler()
为什么没有完成或调用async_receive_from的想法?
答案 0 :(得分:0)
马上,在析构函数中的侦听线程上调用join_all会导致未定义的行为。您正在尝试让服务器在被破坏的过程中保持正常运行。不要这样做。例如,从这些线程运行io_service,您将拥有绑定到this*
的处理程序,这些线程将挂钩。在析构函数中,this*
不再是有效对象。在所有回调中,您应该检查传递的错误参数以查看它是否已设置。
if(error)
{
std::cout << "Error in MyClass::MyFunc(...): " << error << std::endl;
}
..将错误打印到控制台。保证你会在:: bind中看到一个错误,例如这样的错误对象。
您应该在服务器主服务器内部执行某些操作,以防止主服务器退出。将运行服务器的io_service和io_service本身的线程组移到服务器对象之外。使用::work()对象包装io_service,以防止io_service在认为它已停止工作时停止运行(不再需要处理连接)。
除此之外,最简单的方法是指向成熟的TCP和UDP客户端以及提升文档提供的服务器示例。 http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/examples.html