BOOST::ASIO回显服务器
一、需要注意的坑
server端
- std::ostringstream在接收数据前要清空
- boost::asio::streambuf将数据读出后也需要清空-consume()函数
server和client端
- 一个socket数据发送以及接受都结束之后,需要将其关闭sock.close()
- read_until需要配合boost::asio::streambuf使用
二、代码
server端
#include <iostream>
#include <sstream>
#include <functional>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/system/error_code.hpp>
using namespace boost::asio;
void handle_connections()
{
io_service ios;
boost::asio::streambuf buff;
std::ostringstream copy;
ip::tcp::endpoint ep = ip::tcp::endpoint(ip::tcp::v4(), 9999);
ip::tcp::acceptor acceptor(ios, ep);
std::string msg("");
while (true) {
ip::tcp::socket sock(ios);
acceptor.accept(sock);
size_t bytes = read_until(sock, buff, '\n');
copy.str("");
copy << &buff;
buff.consume(bytes);
msg = copy.str();
std::cout << "server receive message: " << copy.str() << std::unitbuf;
sock.write_some(buffer(msg));
sock.close();
}
}
int main(int argc, char* argv[])
{
handle_connections();
}
client端
#include <iostream>
#include <sstream>
#include <vector>
#include <functional>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
using namespace boost::asio;
using namespace boost::system;
void sync_echo(std::string msg)
{
msg.append("\n");
io_service io_server;
ip::tcp::socket sock(io_server);
ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 9999);
sock.connect(ep);
sock.write_some(buffer(msg));
boost::asio::streambuf buf;
int bytes = read_until(sock, buf, "\n");
if(bytes == 0) {
std::cout << "no message" << std::endl;
return;
}
std::ostringstream copy;
copy << &buf;
std::cout << "server echoed our " << msg << ": " << (copy.str() == msg ? "GOOD" : "FAIL") << std::endl;
sock.close();
}
int main(int argc, char* argv[])
{
std::string messages[4] = {"John says hi", "so does James", "Lucy just got home", "Boost.Asio is Fun!"};
boost::thread_group threads;
for (auto & message : messages) {
threads.create_thread(boost::bind(sync_echo, message));
}
threads.join_all();
}