0

公式の例を参考にして、boost asioとチャットしようとしています。しかし、私は実際に async_read で 2 つの問題を抱えています。まず、クライアントで EoF (ファイルの終わり) と接続 (およびアプリケーション) がすぐに閉じるのはなぜですか?

そして、ChatParticipant の async_read に問題があります。boost::bind の 2 番目の引数として「Shared_from_this()」を渡すと、エラー R6010 が発生しますが、単純な「this」を渡すと、それがありません。 .

ご協力いただきありがとうございます :)

ここに私の関係するコードがあります:

チャットサーバー

    class ChatServer
    {
    public:
        ChatServer(boost::asio::io_service& io_service, const tcp::endpoint& endpoint): _io_service(io_service), _acceptor(io_service, endpoint)
        {
            startAccept();
        }

        void startAccept()
        {
            std::cout << "accepting a new client" << std::endl;
            shared_ptr<ServerParticipant> newParticipant(new ServerParticipant(_io_service, &_room));
            _acceptor.async_accept(newParticipant->getSocket(), boost::bind(&ChatServer::handleAccept, this, boost::asio::placeholders::error, newParticipant));
        }

        void handleAccept(const boost::system::error_code& e, shared_ptr<ServerParticipant> newParticipant)
        {
            if (!e)
            {

                std::cout << "accepted a new client" << std::endl;
                boost::asio::async_read(newParticipant->getSocket(),
                    boost::asio::buffer(_readMsgCache.getAllMessage(), ChatMessage::header_length),
                    boost::bind(&ChatServer::read, this,
                boost::asio::placeholders::error));
                //newParticipant->start();
                startAccept();
            }
            else
            {
                std::cerr << e.message() << std::endl;
            }
        }

        void read(const boost::system::error_code& e)
        {
            if (e && e == boost::asio::error::eof)
            {
                std::cerr << "closed" << std::endl;
            }
            if (e)
            {
                std::cerr << e.message() << std::endl;
            }

            else
            {
                std::cout << "Reaaad" << std::endl;
            }

        }
    private:
        boost::asio::io_service& _io_service;
        tcp::acceptor _acceptor;
        ChatMessage _readMsgCache;
}

チャット参加者

    class ChatParticipant : public boost::enable_shared_from_this<ChatParticipant>
    {
    public :
        ChatParticipant(boost::asio::io_service& service) : _id(0), _service(service), _socket(service)
        {}

        virtual void start()
        {
            startRead();
        }

        void startRead()
        {
            std::cout << "Start read" << std::endl;
            boost::asio::async_read(_socket,
                boost::asio::buffer(_readMsgCache.getAllMessage(), 4),
            boost::bind(
            &ChatParticipant::readHeader, shared_from_this(),
              boost::asio::placeholders::error));
        }
// some functions about decoding the message...

protected:
    int _id;
    boost::asio::io_service& _service;
    tcp::socket _socket;


    std::deque<ChatMessage> _writeMsgCache;
    ChatMessage _readMsgCache;

チャット クライアント

using boost::asio::ip::tcp;

class ChatClient
{
public:
    ChatClient(boost::asio::io_service& service, tcp::endpoint& endpoint) : _service(service), _client(service)
    {
        _client.getSocket().async_connect(endpoint, boost::bind(&ChatClient::handleConnect, this, boost::asio::placeholders::error));
    }


    void handleConnect(const boost::system::error_code& err)
    {

        if (err)
        {
            std::cerr << err.message();
        }
        else
        {
            _client.start();

            /*
            ChatMessage message;
            message.setMessage("hello");
            _client.speak(message);
            */
        }
    }

    void read(const boost::system::error_code& e)
    {
        if (e)
        {
            std::cerr << e.message() << std::endl;
        }
        else
        {
            std::cout << "Reaaad" << std::endl;
        }

    }
protected :
    boost::asio::io_service& _service;
    ChatParticipant _client;
};

チャットメッセージ

#pragma once
#include <stdlib.h>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

using namespace std;
class ChatMessage
{
public :
    enum{header_length = 4};
    static const size_t headerLength = 4; 
    static const size_t maxMsgLength = 512;

    ChatMessage()
    {
        clear();
    }

    void clear()
    {
        for (size_t i = 0; i <= maxLength() ; ++i)
            _allMessage[i] = '\0';
    }

    char* getAllMessage()
    {
        return _allMessage;
    }

    const char* getAllMessage() const
    {
        return _allMessage;
    }

    char* getBody()
    {
        return _allMessage + headerLength;
    }

    size_t getBodyLength()
    {
        return _bodyLength;
    }

    size_t length()
    {
        return headerLength + _bodyLength;
    }

    const size_t length() const
    {
        return headerLength + _bodyLength;
    }

    size_t maxLength()
    {
        return headerLength + maxMsgLength;
    }

    bool setBody(const char* message)
    {
        _bodyLength = strlen(message);
        if (_bodyLength > maxMsgLength)
            return false;
        memcpy(getBody(), message, _bodyLength);
        return true;
    }

    bool setMessage(const char* message)
    {
        clear();
        if (!setBody(message))
            return false;
        encodeHeader();
        return true;
    }
    #pragma warning(disable: 4996) /* Disable deprecation */
    bool decodeHeader()
    {
        char header[headerLength + 1] = "";
        strncat(header, _allMessage, headerLength);
        _bodyLength = atoi(header);
        if (_bodyLength > maxMsgLength)
            return false;
        return true;
    }

    void encodeHeader()
    {
        stringstream ss;
        ss << setw(headerLength) << _bodyLength;
        string s(ss.str());
        memcpy(_allMessage,s.c_str(), headerLength);

    }

private :
    char _allMessage[headerLength + maxMsgLength];
    size_t _bodyLength;
};

主要

#include "ChatMessage.h"


#define IsServer true
#ifdef IsServer
    #include "ChatServer.h"
#else
    #include "ChatCLient.h"
#endif

using boost::asio::ip::tcp;
int main()
{
    boost::asio::io_service service;

    #ifdef IsServer
        tcp::endpoint endpoint(tcp::v4(), 13);
        std::cout << "Server start" << std::endl;
        ChatServer server(service, endpoint);
    #else
        tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), 13);
        std::cout << "Client start" << std::endl;
        ChatClient client(service, endpoint);
    #endif

    service.run();
    return 0;
}
4

2 に答える 2

0

変化する

ChatParticipant _client;

boost::shared_ptr<ChatParticipant> _client;

_clientctor 初期化リストでポインタを初期化します。これにより、呼び出してtoshared_from_this()を取得できます。shared_ptr_client

于 2013-11-01T18:25:38.203 に答える