Let us suppose that a client holds two different big objects (in terms of byte size) and serializes those followed by sending the serialized objects to a server over TCP/IP network connection using boost::asio
.
-
For client side implementation, I'm using
boost::asio::write
to send binary data (const char*
) to the server. -
For server side implementation, I'm using
read_some
rather thanboost::asio::ip::tcp::iostream
for future improvement for efficiency. I built the followingrecv
function at the server side. The second parameterstd::stringstream &is
holds a big received data (>65536 bytes) in the end of the function.
When the client side calls two sequential boost::asio::write
in order to send two different binary objects separately, the server side sequentially calls two corresponding recv
as well. However, the first recv
function absorbs all of two incoming big data while the second call receives nothing ;-(. I am not sure why this happens and how to solve it.
Since each of two different objects has its own (De)Serialization function, I'd like to send each data separately. In fact, since there are more than 20 objects (not just 2) that have to be sent over the network.
void recv (
boost::asio::ip::tcp::socket &socket,
std::stringstream &is) {
boost::array<char, 65536> buf;
for (;;) {
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
std::cout << " read "<< len << " bytes" << std::endl; // called multiple times for debugging!
if (error == boost::asio::error::eof)
break;
else if (error)
throw boost::system::system_error(error); // Some other error.
std::stringstream buf_ss;
buf_ss.write(buf.data(), len);
is << buf_ss.str();
}
}
Client main file:
int main () {
... // some 2 different big objects are constructed.
std::stringstream ss1, ss2;
... // serializing bigObj1 -> ss1 and bigObj2-> ss2, where each object is serialized into a string. This is due to the dependency of our using some external library
const char * big_obj_bin1 = reinterpret_cast<const char*>(ss1.str().c_str());
const char * big_obj_bin2 = reinterpret_cast<const char*>(ss2.str().c_str());
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(big_obj_bin1, ss1.str().size()), ignored_error);
boost::asio::write(socket, boost::asio::buffer(big_obj_bin2, ss2.str().size()), ignored_error);
... // do something
return 0;
}
Server main file:
int main () {
... // socket is generated. (communication established)
std::stringstream ss1, ss2;
recv(socket,ss1); // this guy absorbs all of incoming data
recv(socket,ss2); // this guy receives 0 bytes ;-(
... // deserialization to two bib objects
return 0;
}
Aucun commentaire:
Enregistrer un commentaire