Отправленные и полученные данные не имеют одинаковый размер - PullRequest
0 голосов
/ 17 марта 2011

У меня есть сервер на C ++, написанный с boost.asio и php клиентом.когда я отправляю небольшое количество данных, я получаю все данные, но когда я отправляю длинную строку, я теряю большую ее часть.

Вот часть, где я отправляю данные с моего сервера, он говорит, что я отправил 65536байты

void handle_write(const boost::system::error_code& /*error*/,
            size_t size/*bytes_transferred*/) {
        cout <<size<<endl;
    }
    void handler_read(const boost::system::error_code&, std::size_t size) {
        istream is(&buffer);
        string myString;
        getline(is, myString);

        Manager myManager(myString);
        string response = myManager.getResponse();
        boost::asio::async_write(socket_,
                boost::asio::buffer(response),
                boost::bind(&tcp_connection::handle_write, shared_from_this(),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));

    }

Здесь я создаю строку, которую я буду отправлять

string getMap(string name, string pass) {
            if (name == "admin" && pass == "123") {
                string response = "";
                ConvertTypes types;
                response = types.intToString(MAP_HEIGHT) + " ";
                response += types.intToString(MAP_WIDTH) + "\r\n";
                for (int i=0; i<MAP_HEIGHT;i++) {
                    for (int j=0;j<MAP_WIDTH;j++) {
                        response += types.intToString(
                                worldMap[i][j].getHeight()) + " ";
                        response += types.intToString(
                                worldMap[i][j].getIsTown()) + " ";
                        response += string (1, worldMap[i][j].getTetrain())
                                +"\r\n";
                    }
                }
                return response;
            } else {
                return "";
            }
        }

На стороне php я читаю отправленные данные, stream_get_meta_data говорит, что получил только 8183 байта данных.

print_r($this->socket->getStatus());

        for ($i=0; $i<$MAP_HEIGHT;$i++) {
            for ($j=0; $j<$MAP_WIDTH;$j++) {

                $this->response = $this->socket->readLine();
                $this->response = explode(' ', $this->response);
                echo "<p>";
                echo "$i $j <br>";
                print_r($this->response);
                echo '<br>';
                print_r($keyArray);
                $map[$i][$j] = array_combine($keyArray, $this->response);
                $this->response = $this->socket->readLine();
            } }

        }

Ответы [ 2 ]

2 голосов
/ 17 марта 2011

Вы можете отправить один большой блок через сокет, но принимающая сторона может получить несколько блоков меньшего размера, например:

send    -> 10000 bytes

receive <- 3000 bytes
receive <- 2000 bytes
receive <- 4500 bytes
receive <-  500 bytes

это только пример, TCP не гарантирует, что блоки отправки и получения будут одинакового размера.

0 голосов
/ 18 марта 2011

Я нашел ответ. Я отправлял данные с сервера небезопасным способом. Когда async_write отказался от управления чем-то другим, остальные данные были потеряны.

Вы должны передать строку этому классу:

class shared_const_buffer {
public:
  // Construct from a std::string.
  explicit shared_const_buffer(const std::string& data)
    : data_(new std::vector<char>(data.begin(), data.end())),
      buffer_(boost::asio::buffer(*data_))
  {
  }

  // Implement the ConstBufferSequence requirements.
  typedef boost::asio::const_buffer value_type;
  typedef const boost::asio::const_buffer* const_iterator;
  const boost::asio::const_buffer* begin() const { return &buffer_; }
  const boost::asio::const_buffer* end() const { return &buffer_ + 1; }

private:
  boost::shared_ptr<std::vector<char> > data_;
  boost::asio::const_buffer buffer_;
};

и отправьте этот буфер не необработанной строкой. Таким образом, вы не потеряете данные.

...