在循环调用中,asio :: async_write()数据在接收点损坏。
但是,如果调用asio :: async_write()之间在1 ms内插入暂停,则数据将被正确读取。
此问题的示例:http://rghost.ru/4908432
#ifndef _header_hpp_included_
#define _header_hpp_included_
#include <iostream>
#include <sstream>
#include <cstdio>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/lexical_cast.hpp>
enum { recv_buffer_size = 13 };
enum { send_buffer_size = 13 };
volatile size_t counter = 0;
/***************************************************************************/
void client_readed(boost::asio::ip::tcp::socket&, boost::shared_array<char>, const boost::system::error_code&);
/** client read the reply from the server */
void client_read(boost::asio::ip::tcp::socket& sock) {
boost::shared_array<char> buf(new char[recv_buffer_size]);
boost::asio::async_read(
sock,
boost::asio::buffer(buf.get(), recv_buffer_size),
boost::bind(
&client_readed,
boost::ref(sock),
buf,
boost::asio::placeholders::error
)
);
}
/** when the whole packet is read client check it's index */
void client_readed(boost::asio::ip::tcp::socket& sock, boost::shared_array<char> buf, const boost::system::error_code& e) {
if ( e ) {
if ( !counter ) return;
std::cout << "read handler: " << e.message() << std::endl;
return;
}
counter--;
#ifdef _my_debug_
printf("client_readed(): %s", buf.get());
fflush(stdout);
#endif
static size_t idx = 0;
size_t tmp = 0;
char* p = strchr(buf.get(), ':');
if ( p ) {
p++;
sscanf(p, "%8d", &tmp);
} else {
throw std::runtime_error("input data error!");
}
if ( idx != tmp ) {
std::ostringstream os;
os << "read error. expected " << idx << " get " << tmp;
throw std::runtime_error(os.str());
}
idx++;
client_read(sock);
}
/***************************************************************************/
void writen(boost::shared_array<char>, const boost::system::error_code&);
/** client send the packet to the server */
void start_write(boost::asio::ip::tcp::socket& sock, boost::shared_array<char> buf) {
counter++;
boost::asio::async_write(
sock,
boost::asio::buffer(buf.get(), send_buffer_size),
boost::bind(
&writen,
buf,
boost::asio::placeholders::error
)
);
}
void writen(boost::shared_array<char> buf, const boost::system::error_code& e) {
if ( e ) {
std::cout << "writen(): " << e.message() << std::endl;
}
}
/***************************************************************************/
void server_readed(boost::asio::ip::tcp::socket&, boost::shared_array<char>, const boost::system::error_code&);
/** async reading incoming packet at the server side */
void server_read(boost::asio::ip::tcp::socket& sock) {
boost::shared_array<char> buf(new char[recv_buffer_size]);
boost::asio::async_read(
sock,
boost::asio::buffer(buf.get(), recv_buffer_size),
boost::bind(
&server_readed,
boost::ref(sock),
buf,
boost::asio::placeholders::error
)
);
}
/** when the whole packet is read send it back to the client */
void server_readed(boost::asio::ip::tcp::socket& sock, boost::shared_array<char> buf, const boost::system::error_code& e) {
if ( e ) {
std::cout << "read handler: " << e.message() << std::endl;
return;
}
#ifdef _my_debug_
printf("server_readed(): %s", buf.get());
#endif
static const char* ptr = "sc:";
memcpy(buf.get(), ptr, strlen(ptr));
start_write(sock, buf);
server_read(sock);
}
/***************************************************************************/
/** this functional object execute in the boost::thread at the client side */
struct async_test {
async_test(boost::asio::ip::tcp::socket& sock, volatile bool& run)
:_sock(sock),
_run(run)
{}
void operator()() {
for ( size_t idx = 0; _run; ++idx ) {
boost::shared_array<char> buf(new char[send_buffer_size]);
sprintf(buf.get(), "cs:%8d\n", idx);
start_write(_sock, buf);
}
}
private:
boost::asio::ip::tcp::socket& _sock;
volatile bool& _run;
};
/***************************************************************************/
#endif // _header_hpp_included_
答案 0 :(得分:2)
您的示例不显示顶级用法,线程等。
检查是否同时从不同的线程发送到同一个套接字,这可能是个问题。按顺序执行
答案 1 :(得分:0)
在这种情况下,数据损坏很可能是因为您正在使用async_read,并且在async_read处理程序中,再次调用async_read(在处理程序之后没有时间进行清理)。