5

私はboost::asioを使用して読み取り/書き込み操作を行うC++サーバーを持っています-メッセージの書き込みは正常に機能します-それでも何らかの理由で読み取りを機能させることができません

クライアントから送信しているメッセージは1516ビット符号なしショートです-私のテストメッセージは次のとおりです。

1, 34, 7, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0

今サーバー上で私はこのようなものを絶えず見ています。読み取りはしばしば分割され、および/または256で乗算されます

これは2回送信する1回の実行です

reading length = 8: [1 34 7 0 0 0 0 0]
reading length = 3: [1024 0 0]
reading length = 3: [0 0 0]
reading length = 8: [1 34 7 0 0 0 0 0]
reading length = 6: [1024 0 0 0 0 0]

これは2回送信する2回目の実行です

reading length = 8: [1 34 7 0 0 0 0 0]
reading length = 6: [1024 0 0 0 0 0]
reading length = 6: [1 34 7 0 0 0]
reading length = 1: [0] 
reading length = 0: []
reading length = 0: []
reading length = 2: [0 0]
reading length = 2: [0 0]
reading length = 1: [0]

これは1回送信する3回目の実行です(ここで何が起こったのかわかりません)

reading length = 14: [256 8704 1792 0 0 0 0 0 1024 0 0 0 0 0]

これが実際のサーバー読み取りコードです

void Session::start(void) {
  msg_interface->add_msg_listener(this);
  _socket.async_read_some(
    boost::asio::buffer(_read_data_buffer, READ_DATA_BUFFER_LENGTH),
    boost::bind(&Session::handle_read, this, boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
}

void Session::handle_read(const boost::system::error_code& error, std::size_t bytes_transferred) {
  if (error) {
    msg_interface->remove_msg_listener(this);
    delete this;
  } else {
    if (bytes_transferred != 0) {
      // print what we've received
      const int length = bytes_transferred / sizeof(uint16_t);
      std::cout << "reading length = " << length << ": [";
      for (int i = 0; i < length; i++) {
        const uint16_t data = ntohs(_read_data_buffer[i]);
        std::cout << data;
        if (i != length - 1) {
          std::cout << " ";
        }
      }
      std::cout << "]" << std::endl;
    }
    _socket.async_read_some(
      boost::asio::buffer(_read_data_buffer, READ_DATA_BUFFER_LENGTH),
      boost::bind(&Session::handle_read, this, boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));
  }
}

変数は次のとおりです

const int READ_DATA_BUFFER_LENGTH = 1024;

class AbstractSession {
protected:
  uint16_t _read_data_buffer[READ_DATA_BUFFER_LENGTH];
...

1つあります。同じIOサービスを使用して、受信時にメッセージを書き込み(サーバーは古いインターフェイスと通信し、受信したメッセージをすべてのクライアントに送信します)、クライアントからのメッセージを読み取ります。両方に同じioサービスを使用すると、これが発生する可能性がありますか?

これを修正するために私が何をすべきかについての考えはありますか?

4

1 に答える 1

4

あなたのコードはそれがすることになっていることをします-それはそれができる限り多くのデータを読みます。これが、関数async_read_some名が「some」で終わる理由です。「some」バイトを読み取り、それ以上のことを約束するものではありません。ドキュメントには次のようにも書かれています。

非同期操作が完了する前に、要求された量のデータが確実に読み取られるようにする必要がある場合は、async_read関数の使用を検討してください。

部分的な読み取りを処理するようにレシーバーを作り直さない限り、これはあなたのケースのように思えます。

于 2012-06-18T13:55:19.247 に答える