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 开发者_Python百科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();
} }
}
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.
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.
精彩评论