所以我试图编写一个通过tcp套接字读写数据的程序。我可以成功接受连接,向它写入数据(虽然写处理程序不能按预期工作?)。我也想通过相同的套接字读取数据 - 这似乎不起作用。 处理所有这些的类如下:
using namespace boost::asio;
using namespace boost::asio::ip;
TcpServer::TcpServer(unsigned short port = 1700)
: ipPort(port){
tcp::acceptor acc(svc, tcp::endpoint(tcp::v4(), ipPort));
acc.listen();
acc.async_accept(socket, boost::bind(&TcpServer::Accept_Handler,this, placeholders::error));
SAY("Waiting for a New connection");
svc.run();
}
void TcpServer::Write_Handler(const boost::system::error_code& ec,
std::size_t bytes_transferred){
std::cout << ec.message() << std::endl;
if (!ec)
{
std::cout << "Just sent " << yawData << std::endl;
}
}
void TcpServer::Read_Handler(const boost::system::error_code& ec,
std::size_t bytes_transferred){
if (!ec)
{
std::string line;
std::istream is(&input_buffer_);
std::string test;
is >> test;
std::cout << "test" << test << std::endl;
std::getline(is, line);
if (!line.empty())
{
std::cout << "Recieved: " << line << std::endl;
}
}
else
std::cout << "Error reading:" << ec.message() << std::endl;
}
void TcpServer::Accept_Handler(const boost::system::error_code& ec){
if (!ec)
{
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
connectMode = 1;
}
}
void TcpServer::Write_Data(){
if (connectMode){
SAY("Sent data");
std::ostringstream ss;
std::string sendBuffer;
ss << std::fixed << std::setprecision(2);
ss << yawData;
sendBuffer = ss.str() + "\r";
async_write(socket, buffer(sendBuffer), boost::bind(&TcpServer::Write_Handler, this,
placeholders::error,
placeholders::bytes_transferred));
}
}
void TcpServer::UpdateYaw(double data) {
yawData = data;
}
void TcpServer::Read_Data(){
if (connectMode){
async_read_until(socket, input_buffer_, "\n" , boost::bind(&TcpServer::Read_Handler, this,
placeholders::error,
placeholders::bytes_transferred));
}
}
TcpServer::~TcpServer(){
svc.stop();
}
类标题如下:
class TcpServer {
private:
io_service svc;
tcp::socket socket{svc};
double yawData = 0;
unsigned short ipPort;
bool connectMode = 0;
streambuf input_buffer_;
void Write_Handler(const boost::system::error_code&,
std::size_t);
void Read_Handler(const boost::system::error_code&,
std::size_t);
void Accept_Handler(const boost::system::error_code&);
public:
TcpServer(unsigned short );
void Write_Data();
void Read_Data();
void UpdateYaw(double);
~TcpServer();
};
要使用它,我调用Write_Data(),然后调用Read_Data()。 Write_Data有效,但写入处理程序未被调用 - 我可以在客户端接收数据。 Read_Data()根本不起作用。我确信数据是通过套接字以所需的格式发送的(以“\ n”结尾)
关于什么可能出错或任何调试技巧的想法?
由于
修改
我计划从main函数运行write_data和read_data函数,如下所示:
TcpServer *socketObj = new TcpServer(1700);
while ( i < 100 && trackObj->ReadTrackingState() != 0) {
SAY("Current Yaw - %.02f", trackObj->CurrentYaw());
socketObj->UpdateYaw(trackObj->CurrentYaw());
socketObj->Write_Data();
socketObj->Read_Data();
Platform::sleepMillis(1000);
i++;
}
答案 0 :(得分:1)
void TcpServer::Accept_Handler(const boost::system::error_code &ec) {
if (!ec) {
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
connectMode = 1;
}
}
此功能结束异步处理。它没有安排任何更多的异步工作,因此io_service::run()
结束,如文档所示。
您希望直接链接或使用io_service::work
来保持服务正常运行。我建议链接:
void TcpServer::Accept_Handler(const boost::system::error_code &ec) {
if (!ec) {
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
Write_Data();
}
}
但是......
您需要仔细查看所有代码。
void TcpServer::Write_Data() {
SAY("Sent data");
std::ostringstream ss;
std::string sendBuffer;
ss << std::fixed << std::setprecision(2);
ss << yawData;
sendBuffer = ss.str() + "\r";
async_write(socket, buffer(sendBuffer),
boost::bind(&TcpServer::Write_Handler, this, placeholders::error, placeholders::bytes_transferred));
}
这里发生了什么?首先,您创建一个临时流,无法使用它来附加回车符,然后将引用传递给本地字符串async_write
......这无法正常工作。它是Undefined Behaviour。
修复:
void TcpServer::Write_Data() {
SAY("Send data");
std::ostream ss(&output_buffer_);
ss << std::fixed << std::setprecision(2) << yawData << "\r";
async_write(socket, output_buffer_,
boost::bind(&TcpServer::Write_Handler, this, placeholders::error, placeholders::bytes_transferred));
}
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <iomanip>
using namespace boost::asio;
using namespace boost::asio::ip;
template <typename T>
static inline void SAY(T&& v) { std::cout << std::forward<T>(v) << "\n"; }
class TcpServer {
private:
io_service svc;
tcp::socket socket{ svc };
double yawData = 0;
unsigned short ipPort;
streambuf input_buffer_, output_buffer_;
void Write_Handler(const boost::system::error_code &, std::size_t);
void Read_Handler(const boost::system::error_code &, std::size_t);
void Accept_Handler(const boost::system::error_code &);
public:
TcpServer(unsigned short = 1700);
void Write_Data();
void Read_Data();
void UpdateYaw(double);
~TcpServer();
};
TcpServer::TcpServer(unsigned short port) : ipPort(port) {
tcp::acceptor acc(svc, tcp::endpoint(tcp::v4(), ipPort));
acc.listen();
acc.async_accept(socket, boost::bind(&TcpServer::Accept_Handler, this, placeholders::error));
SAY("Waiting for a New connection");
svc.run();
}
void TcpServer::Write_Handler(const boost::system::error_code &ec, std::size_t /*bytes_transferred*/) {
std::cout << ec.message() << std::endl;
if (!ec) {
std::cout << "Just sent " << yawData << std::endl;
Read_Data();
}
}
void TcpServer::Read_Handler(const boost::system::error_code &ec, std::size_t /*bytes_transferred*/) {
if (!ec) {
std::cout << "Recieved: " << &input_buffer_ << std::endl;
} else
std::cout << "Error reading:" << ec.message() << std::endl;
}
void TcpServer::Accept_Handler(const boost::system::error_code &ec) {
if (!ec) {
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
Write_Data();
}
}
void TcpServer::Write_Data() {
SAY("Send data");
std::ostream ss(&output_buffer_);
ss << std::fixed << std::setprecision(2) << yawData << "\r";
async_write(socket, output_buffer_,
boost::bind(&TcpServer::Write_Handler, this, placeholders::error, placeholders::bytes_transferred));
}
void TcpServer::UpdateYaw(double data) { yawData = data; }
void TcpServer::Read_Data() {
async_read_until(socket, input_buffer_, "\n", boost::bind(&TcpServer::Read_Handler, this, placeholders::error,
placeholders::bytes_transferred));
}
TcpServer::~TcpServer() { svc.stop(); }
int main() {
TcpServer server;
}