【问题标题】:Boost Asio io_service, Read Messages from ClientBoost Asio io_service,从客户端读取消息
【发布时间】:2011-01-06 20:25:09
【问题描述】:

我正在尝试使用 Boost ASio 库在 C++ 中创建一个简单的 Tcp 服务器。我写了两个类 TcpConnection 和 TcpServer。

我需要的行为是 Tcp 服务器应该能够向所有连接的客户端发送消息,并且客户端应该能够向服务器注册/注销。

我能够实现从服务器发送消息。我没有成功阅读客户部分。我的客户端是用 java 编写的,使用 apache mina。

服务器代码

message = message + "\r\n"; 
const int bytesToSend = message.length(); 
boost::system::error_code error;
boost::asio::write(socket, boost::asio::buffer(message, bytesToSend), boost::asio::transfer_all(), error);

客户端代码

ConnectFuture future = ioConnector.connect(new InetSocketAddress(Port),
                new TriggerReceiverHandler();
System.out.println("Message Receiver started and listening on port "+ Port);
IoSession session = future.getSession();
session.write(new String("TEst Message From Client"));

在服务器上,读取消息的代码是使用 async_read 完成的

boost::array<char, 1> buf;
    boost::asio::async_read(socket, boost::asio::buffer(buf),
        boost::bind(&TcpConnection::handleRead, this, buf, boost::asio::placeholders::error));


void TcpConnection::handleRead(boost::array<char, 1> buf, const boost::system::error_code& error)
{
    if(!error)
    {
        std::cout << "Message: " << buf.data() << std::endl;
    }
    else
    {
        std::cout << "Error occurred." << std::endl;
    }
}

但是,当我通过从客户端写入会话来触发消息时,不会调用 handleRead。如果我做错了什么,请告诉我。

我将不胜感激。如果需要任何进一步的信息,请告诉我。

提前致谢。

【问题讨论】:

  • 我建议你用 C++ 和 Java 编写一个服务器和客户端来比较它们是如何操作的。 Java 客户端和服务器应该能够相互通信,C++ 客户端和服务器也应该能够通信。这样您就可以诊断出哪一端有问题。

标签: java c++ tcp boost-asio


【解决方案1】:

首先这似乎是不正确的!

boost::array<char, 1> buf;

您正在声明一个大小为 1 的数组!我会建议更大的东西!

boost::array<char, 1500> buf;

除了缓冲区之外,我看不出您的代码有任何问题,只需检查您是否没有在同一个套接字上交错 async_read 调用。

【讨论】:

  • 我不清楚“只是检查你没有在同一个套接字上交错 async_read 调用”。意思是。我应该打开两个插座,一个用于阅读,一个用于书写吗?我认为那是错误的。你能详细说明一下吗?
  • 不,这意味着在前一个调用完成(即调用处理程序)之前,您绝不能在特定套接字上调用async_read
  • 好的 明白了...不过有一个问题...当客户端发送消息时,我怎么知道要阅读?现在我只是定期阅读,到时候缓冲区已满并溢出。读取后清除缓冲区也是一种好习惯吗?
  • 你不需要,只要你的句柄操作可以接受一个大小来表明你在缓冲区中有多少。使用async_read,您应该在连接的那一刻调用async_read(异步等待来自客户端的数据-您不需要轮询),当有数据时,asio会回拨您。在那个处理程序中,设置下一个async_read - 实际上最好的方式是想象这是你告诉 asio,当将来有来自套接字的一些数据时让我知道。
  • 非常感谢!这清除了一切..但我的问题还没有解决。除非我手动触发 readMessage() 函数,否则不会调用处理程序