c++ - boost/asio : Very simple chat server can't access the messages that are recieved

标签 c++ c++11 visual-c++ boost boost-asio

我正在学习 boost 并且正在弄乱它的服务器和客户端通信以制作一个简单的聊天服务器,客户端发送的任何内容都只显示在服务器上。服务器本身不发送任何内容并启动接收部分。这非常简单。

服务器代码:

#include <boost\asio\placeholders.hpp>
#include <boost\bind.hpp>
#include <boost\asio\ip\tcp.hpp>
#include <boost\asio\io_context.hpp>
#include <iostream>

class Server
{
private :
    boost::asio::ip::tcp::socket server_socket;
    boost::asio::ip::tcp::endpoint server_endpoint;
    boost::asio::ip::tcp::acceptor acceptor;
    std::string msg;

public :
    Server(boost::asio::io_context &io) :
    server_socket(io),
    server_endpoint(boost::asio::ip::make_address("127.0.0.1"), 27015),
    acceptor(io, server_endpoint)
    {
        acceptor.async_accept(server_socket,
            boost::bind(&Server::async_acceptor_handler, this,
                boost::asio::placeholders::error));
    }

    void async_acceptor_handler(const boost::system::error_code &ec)
    {
        if (!ec)
        {
            std::cout << "One client connected...\n";

            server_socket.async_read_some(boost::asio::buffer(msg),
                boost::bind(&Server::async_read_some_handler, this, 
                    boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "async_acceptor failed with error code : " << ec.value() << std::endl;
            std::cout << "Error description : " << ec.message() << std::endl;
        }
    }

    void async_read_some_handler(const boost::system::error_code &ec)
    {
        if (!ec)
        {
            std::cout << msg << std::endl;

            server_socket.async_read_some(boost::asio::buffer(msg),
                boost::bind(&Server::async_read_some_handler, this, 
                    boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "async_acceptor failed with error code : " << ec.value() << std::endl;
            std::cout << "Error description : " << ec.message() << std::endl;
        }
    }
};

int main()
{
    boost::asio::io_context io;
    Server s(io);

    io.run();
    return 0;
}

在客户端部分,它又是一个非常直接的代码,只需连接到服务器并开始从用户那里获取输入并发送到服务器。

客户端代码:

#include <boost\asio\placeholders.hpp>
#include <boost\bind.hpp>
#include <boost\asio\ip\tcp.hpp>
#include <boost\asio\io_context.hpp>
#include <iostream>

class Client
{
private :
    boost::asio::ip::tcp::socket client_socket;
    boost::asio::ip::tcp::endpoint server_endpoint;
    std::string msg;

public :
    Client(boost::asio::io_context &iocontext) :
        client_socket(iocontext),
        server_endpoint(boost::asio::ip::make_address("127.0.0.1"), 27015)
    {
        //connect to server endpoint
        client_socket.async_connect(server_endpoint, 
            boost::bind(&Client::async_connect_handler, this, 
                boost::asio::placeholders::error));
    }

    void async_connect_handler(const boost::system::error_code &ec)
    {
        if (!ec)
        {
            std::cout << "Connected to chat server...\n";

            //wait for user input
            std::cin >> msg;
            std::cout << "\rC : " << msg << std::endl;

            client_socket.async_write_some(boost::asio::buffer(msg),
                boost::bind(&Client::async_write_some_handler, this, 
                    boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "async_connect failed with error code : " << ec.value() << std::endl;
            std::cout << "Error description : " << ec.message() << std::endl;
        }
    }

    void async_write_some_handler(const boost::system::error_code &ec)
    {
        //wait for user input
        std::cin >> msg;
        std::cout << "\rC : " << msg << std::endl;

        client_socket.async_write_some(boost::asio::buffer(msg),
            boost::bind(&Client::async_write_some_handler, this, 
                boost::asio::placeholders::error));
    }
};

int main()
{
    boost::asio::io_context io;
    Client c(io);

    io.run();
    return 0;
}

现在问题:

它工作正常,也连接到服务器。我在客户端和服务器中得到正确的“连接到聊天服务器...”和“一个客户端连接...”。之后问题出现了:

  1. 在服务器控制台中,在“一个客户端”消息之后,它只是开始不打印任何内容,然后继续打印。
  2. 客户端发送的消息永远不会显示在服务器控制台中。

问题 1 可能是我的问题,因为我还没有检查等待函数和其他使服务器等待的调用。如果你能在这方面指导我,那就太棒了。但主要问题问题的第 2 部分,因为,我不知道为什么服务器总是从客户端接收不到任何信息。

PS:这是一个不完整的代码,我打算多玩一些,所以,如果有一些重大缺陷,请告诉我......:)

PPS:在你说检查其他与此类似的问题之前,我已经检查了所有类似的问题。例如:thisthis , 但这不相关。

最佳答案

服务器端string msg的大小是多少? 为 0。所以服务器总是读取 0 字节。 当你想读取字符串并调用 buffer::asio::buffer 时,字符串必须有一定的大小,例如 10。这意味着你想将 10 个字节读入 msg。你可以调用msg.resize(10)(在读取操作开始之前),然后一些数据会被async_read_some读取到msg中(它可能是 1,2 个字节,无论如何 - async_read_some 是如何工作的,但最大读取字符数是 10)。但这是一个糟糕的解决方案。

你正在发送文本,所以当你不知道有多少字节可以来自客户端时,你可以考虑使用读取数据到 streambuf 而不是 string .然后你可以调用async_read_until带分隔符 - 例如可以是换行符。

另一个解决方案是使用 dynamic buffer .将数据附加到字符串中的位置,您不关心字符串缓冲区的初始大小。但是动态缓冲区不能与async_read_some这样的套接字成员函数一起使用,它可以作为自由函数与async_read一起使用。

关于c++ - boost/asio : Very simple chat server can't access the messages that are recieved,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55156974/

相关文章:

php - 将 PHP 脚本连接到本地主机上的可执行文件的最佳方法

c++ - 调整任何动态数组大小的函数

c++ - 阿特金筛在非常高的限度下发生故障

c++ - 将浮点值的 std::vector 传递给函数会稍微改变值

c++ - 0xC00000FD(堆栈溢出)错误的参数是什么?

android - 如何为特定构建风格设置 cpp 文件夹

c++ - [[carries_dependency]] 什么意思以及如何实现

c++ - 以方便的方式在 C++ 中使用方法作为回调

c++ - 使用 C++ 更新 XML 节点值

c - 以跨平台方式导出共享库符号?