0

ブースト asio を使用するシンプルなバージョンのクライアントがあります。クライアントは、データを送信すると、サーバーから応答を受け取ると想定されています。ここにクライアントのコードがあります

void RunClient()
    {
        try
        {
            boost::asio::io_service io_service;
            boost::asio::ip::tcp::resolver resolver(io_service);
            boost::asio::ip::tcp::resolver::query query( "127.0.0.1", boost::lexical_cast< std::string >( 7777 )); //9100
            boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            boost::asio::ip::tcp::socket socket(io_service);
            socket.async_receive(boost::asio::buffer(buf_client, 3000), 0, ClientReceiveEvent);

            boost::asio::connect(socket, endpoint_iterator);

            boost::system::error_code ignored_error;
            std::cout << "Sending message \n";
            boost::asio::write(socket, boost::asio::buffer("Data to send"), ignored_error);
            io_service.run();
        }
        catch (std::exception & ex)
        {
            std::cout << "[" << boost::this_thread::get_id()<< "] Exception: " << ex.what() << std::endl;   
        }
    }

これが私のClientReceiveEventです

void ClientReceiveEvent(const boost::system::error_code& error, std::size_t bytes_transferred)
    {
        if(!error)
        {
            std::cout << "Message: " << buf_client.data() << std::endl;

        }
        else
        {
            std::cout << "Error occurred." << error.message() << std::endl;
        }
    }

受信データに対して上記のメソッドからエラーが発生しています

Error occurred.The file handle supplied is not valid

クライアントで私が間違っていることは何か提案はありますか?

アップデート:

私はコードを動作させましたが、なぜステートメントが

socket->async_receive(boost::asio::buffer(buf_client, 3000), 0, ClientReceiveEvent);

接続後に配置する必要があります。そしてなぜ声明

io_service->run();

最後に配置する必要があります。これにより、非同期プロセスが開始されると思いました。

また、サーバーにデータを再送信する方法を知りたいと思っていました。無事に1回送信できました。コマンドを再送信するにはどうすればよいですか?

作業コードは次のとおりです。

boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service);
            boost::shared_ptr< boost::asio::ip::tcp::socket > socket(   new boost::asio::ip::tcp::socket( *io_service ) );
            boost::asio::ip::tcp::resolver resolver(*io_service);
            boost::asio::ip::tcp::resolver::query query( "127.0.0.1", boost::lexical_cast< std::string >( 7777 )); //9100
            boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            socket->connect(endpoint_iterator->endpoint());
            socket->async_receive(boost::asio::buffer(buf_client, 3000), 0, ClientReceiveEvent);
            boost::system::error_code ignored_error;
            std::cout << "Sending message \n";
            boost::asio::write(*socket, boost::asio::buffer("some data"), ignored_error);           
            io_service->run();
4

1 に答える 1

0

async_receiveコードが呼び出された後に実行される読み取りアクションをスケジュールしますが、関数自体をrun()呼び出している時点では、接続されたソケットが必要です。async_receiveこれは、内部的にasync_receive次のように実装されているためです。

this->get_service().async_receive(this->get_implementation(),buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));

この式は、その時点でthis->get_implementation()の内部ソケットハンドルのコピーを返しますが、この場合は接続されていません。

つまり、非同期読み取りがスケジュールされた後は、接続されていないソケットで読み取りがスケジュールされるため、ソケットの接続には役立ちません。

于 2013-03-22T09:44:28.533 に答える