我正在尝试使用boost asio制作tcp echo服务器。 我成功地将字符串数据从客户端传输到服务器。 但是我无法在客户端之间传输接收到的数据。 我不知道此问题是由服务器代码中的async_write()函数还是客户端代码中的async_read()函数引起的。 我想这个问题是由线程的声明和它们的函数调用引起的,但是我不确定。
摘要:我不知道此问题的正确原因。 请帮帮我...
服务器代码
#include <iostream>
#include <boost/asio.hpp>
#include <cstring>
#include <cstdlib>
#include <memory>
#include <deque>
#include <list>
#include <set>
using boost::asio::ip::tcp;
typedef std::string echo_message;
class echo_session
: public std::enable_shared_from_this<echo_session>
{
public:
echo_session(tcp::socket socket, std::set<std::shared_ptr<echo_session>>& session_place)
: socket_(std::move(socket)),
session_place_(session_place)
{
std::cout << "Session Initializing...\n";
read_msg_ = "Server!";
}
void start()
{
int se_num=0;
std::cout << "Session starting...\n";
session_place_.insert(shared_from_this());
for(auto session: session_place_)
{
se_num++;
}
std::cout << "Session num: " << se_num << std::endl;
do_read_message();
}
void deliver(const echo_message& msg)
{
this->write_msg_ = msg;
do_write();
}
private:
void do_read_message()
{
auto self(shared_from_this());
char *read_buffer = new char[128];
std::cout << "Reading Message...\n";
boost::asio::async_read(socket_,
boost::asio::buffer(read_buffer, 128),
[this, self, read_buffer](boost::system::error_code ec, std::size_t)
{
if(!ec)
{
read_msg_ = read_buffer;
std::cout << "do_read_message() Message:" << read_msg_ << std::endl;
/*
/////////////////////////////
Used Debugging Part
////////////////////////////
std::cout << "Async Read! : ";
std::cout << read_msg_ << std::endl;
std::cout << "Length:" << read_msg_.length() << std::endl;
*/
deliver(read_msg_);
do_read_message();
}
else
{
std::cout << "Async Read Failed!\n";
std::cerr << "Error: " << ec.message() << std::endl;
}
});
std::cout << "do_read_message() is returned!\n";
}
void do_write()
{
auto self(shared_from_this());
char *read_buffer = new char[sizeof(write_msg_.c_str())];
memcpy(read_buffer, write_msg_.c_str(), sizeof(write_msg_.c_str()));
boost::asio::async_write(socket_,
boost::asio::buffer(read_buffer, sizeof(read_buffer)),
[this, self, read_buffer](boost::system::error_code ec, std::size_t)
{
if(!ec)
{
std::cout << "Message <" << read_buffer << ">Writed!\n";
this->write_msg_ = "\0";
}
else
{
std::cout << "Write Failed\n";
}
std::cout << "do_write lambda returned!\n";
});
}
tcp::socket socket_;
echo_message read_msg_;
echo_message write_msg_;
std::set<std::shared_ptr<echo_session>>& session_place_;
};
class echo_server {
public:
echo_server(boost::asio::io_context& io_context,
const tcp::endpoint& endpoint)
: acceptor_(io_context, endpoint)
{
do_accept();
}
private:
void do_accept()
{
acceptor_.async_accept(
[this](boost::system::error_code ec, tcp::socket socket)
{
if(!ec)
{
std::make_shared<echo_session>(std::move(socket), sessions_)->start();
std::cout << "Accept!\n";
}
else
{
std::cout << "Accept Failed!\n";
}
do_accept();
});
}
tcp::acceptor acceptor_;
std::set<std::shared_ptr<echo_session>> sessions_;
};
int main(int args, char *argv[])
{
try
{
if( args != 2)
{
std::cerr << "Usage: server <port>" << std::endl;
return 1;
}
boost::asio::io_context io_context;
tcp::endpoint endpoint(tcp::v4(), std::atoi(argv[1]));
echo_server ex_server(io_context, endpoint);
io_context.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
客户代码
#include <iostream>
#include <deque>
#include <thread>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
typedef std::string echo_message;
class echo_client {
public:
echo_client(boost::asio::io_context& io_context,
const tcp::resolver::results_type& endpoints)
: io_context_(io_context),
socket_(io_context)
{
do_connect(endpoints);
}
void write(const std::string string)
{
boost::asio::post(io_context_,
[this, string]()
{
//std::cout << "Post Success!\n";
do_write(string);
});
}
void close()
{
boost::asio::post(io_context_,
[this]()
{
std::cout << "Close Success!\n";
socket_.close();
});
}
private:
void do_connect(const tcp::resolver::results_type& endpoints)
{
boost::asio::async_connect(socket_, endpoints,
[this](boost::system::error_code ec, tcp::endpoint)
{
if(!ec)
{
std::cout << "Async_connect Success!\n";
do_read_message();
}
else
{
std::cout << "Async_connect error!\n";
}
});
}
void do_read_message()
{
std::cout << "read_message()" << std::endl;
//auto self(shared_from_this());
char *read_buffer = new char[128];
boost::asio::async_read(socket_,
boost::asio::buffer(read_buffer, 128),
[this, read_buffer/*, self*/](boost::system::error_code ec, std::size_t size)
{
if(!ec)
{
std::cout << "Async Read Success!\n";
read_msg_ = read_buffer;
if(read_msg_.length() != 0)
{
std::cout << "Message:" << read_msg_ << std::endl;
std::cout << "Length: " << read_msg_.length() << std::endl;
read_msg_ = "\0";
}
do_read_message();
}
else
{
std::cout << "Async_read error!\n";
std::cerr << "Error:" << ec.message() << std::endl;
socket_.close();
}
});
std::cout << "do_read_message() is returned!\n";
}
void do_write(const std::string string)
{
write_msg_ = string;
char *str = new char[sizeof(string.c_str())];
memcpy(str,string.c_str(),sizeof(string.c_str()));
boost::asio::async_write(socket_,
boost::asio::buffer(str, 128),
[this](boost::system::error_code ec, std::size_t)
{
if(!ec)
{
std::cout << "Transport Success!" << std::endl;
}
});
}
private:
boost::asio::io_context& io_context_;
tcp::socket socket_;
echo_message read_msg_;
echo_message write_msg_;
};
int main(int argc, char *argv[])
{
try
{
if(argc != 3)
{
std::cerr << "Usage: client <host> <port>" << std::endl;
return 1;
}
boost::asio::io_context io_context;
tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve(argv[1], argv[2]);
echo_client c(io_context, endpoints);
std::thread t(
[&io_context]()
{
io_context.run();
});
std::string line;
while(std::cin >> line)
{
echo_message msg;
msg = line;
c.write(msg);
}
c.close();
t.join();
}
catch(std::exception e)
{
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}