Я адаптирую пример клиента чата asio из здесь для связи с существующим клиентским приложением, которое публикует строчные данные. Вот мой код:
#include <cstdlib>
#include <deque>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
boost::mutex global_stream_lock;
using boost::asio::ip::tcp;
typedef std::deque<std::string> simple_message_queue;
class chat_client
{
public:
chat_client(boost::asio::io_service& io_service,
tcp::resolver::iterator endpoint_iterator)
: io_service_(io_service),
socket_(io_service)
{
if(DEBUGGING) std::cout << "[" << __FUNCTION__ << "]" << std::endl;
boost::asio::async_connect(socket_, endpoint_iterator,
boost::bind(&chat_client::handle_connect, this,
boost::asio::placeholders::error));
}
void write(const std::string& i_msg)
{
io_service_.post(boost::bind(&chat_client::do_write, this, i_msg));
}
void close()
{
io_service_.post(boost::bind(&chat_client::do_close, this));
}
private:
void handle_connect(const boost::system::error_code& error)
{
if (!error)
{
boost::asio::async_read_until(socket_, simple_msg_buf_, "\n",
boost::bind(&chat_client::handle_read_message, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
void handle_read_message(const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (!error && bytes_transferred)
{
// Remove newline from input.
simple_msg_buf_.commit(bytes_transferred);
std::istream is(&simple_msg_buf_);
std::string s;
is >> s;
std::cout << s << std::endl;
boost::asio::async_read_until(socket_, simple_msg_buf_, "\n",
boost::bind(&chat_client::handle_read_message, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
do_close();
}
}
void do_close()
{
socket_.close();
}
private:
boost::asio::io_service& io_service_;
tcp::socket socket_;
boost::asio::streambuf simple_msg_buf_;
simple_message_queue write_simple_msgs;
};
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("127.0.0.1", "20001");
tcp::resolver::iterator iterator = resolver.resolve(query);
chat_client c(io_service, iterator);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
std::string input;
while(std::cin)
{
std::getline(std::cin,input);
// do something with input...
}
c.close();
t.join();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
У меня нет проблем со связью с сервером, но формат данных, которые я получаю, не такой, каким должен быть. Я хочу разбирать данные построчно, поэтому я использую разделитель "\n"
, как я это делаю в Mac OS X (intel). Например, скажем, я ожидаю, что данные в формате: This:(IS SOME) data;
то, что я на самом деле получаю с кодом выше, имеет форму:
This:(IS
SOME)
data
Похоже, что символ "\n"
обрабатывается так же, как и пробел (" "
).
Фактически, если я заменим разделитель "\n"
на " "
, поведение будет таким же.
Я также пробовал "\r"
и "\r\n"
, но ни один из них не был обнаружен.
Кто-нибудь знает, что может быть причиной этого?