发送和接收的数据大小不同

发布于 2024-10-22 11:02:50 字数 2584 浏览 4 评论 0原文

我有用 boost.asio 和 php 客户端用 C++ 编写的服务器。当我发送少量数据时,我会得到所有数据,但是当我发送长字符串时,我会丢失大部分数据。

这是我从服务器发送数据的部分,它说我已经发送了 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();
            } }

        }

I have server in C++ writen with boost.asio and php client. when i send over small amount of data i get all the data but when i send long string i loose most of it.

Here is the part where i send data from my server, it says i have sent out 65536 bytes

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));

    }

Here i make the string i will be sending

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 "";
            }
        }

On php side i read the sent data, stream_get_meta_data says i only received 8183 bytes of data.

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();
            } }

        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

oО清风挽发oО 2024-10-29 11:02:50

您可以通过套接字发送一个大块,但接收方可能会收到多个较小大小的块,例如:

send    -> 10000 bytes

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

这只是一个示例,TCP 不保证发送和接收块的大小相同。

You can send one large block via socket, but receiving side might get several blocks of smaller sizes, for example:

send    -> 10000 bytes

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

this is only an example, TCP does not guarantee send and receive blocks will be the same size.

转身泪倾城 2024-10-29 11:02:50

我找到了答案。我以不安全的方式从服务器发送数据。当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_;
};

并发送此缓冲区而不是原始字符串。这样您就不会丢失数据。

I've found a answer. I was sending data from server in unsafe way. When async_write gave up controll to something else rest of the data was lost.

You have to pass string to this class:

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_;
};

and send this buffer not raw string. That way you don't loose data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文