주기적 호출 asio :: async_write() 데이터가 수신 지점에서 손상되었습니다.끝점에서의 데이터 손상
그러나 asio :: async_write() 호출 사이에 1ms 이내에 일시 중지를 삽입하면 데이터가 올바르게 읽혀집니다. 이 문제와
#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_
아니라 미래의 어떤 시점에서 존재하지 않을 수 있습니다 외부 웹 사이트보다 여기에 코드를 게시하시기 바랍니다. 코드가 SO 질문에 비해 너무 큰 경우 재현 가능한 예제로 줄이십시오. 문제를 디버그하는 데 도움이됩니다. –
이 코드의 크기를 줄일 수 없으므로이 코드의 모든 부분이 서로 연결됩니다. 나는 실행의 노선을 이해하는 것이 너무 어려울 것이라고 생각한다. – niXman
사람이 포함되어 있어도 zip 파일을 다운로드하지 않습니다. 그 일을 돕기 위해 우리 측에서 추가 작업이 필요합니다. 문제를 더 작은 예제로 줄임으로써 도움을 주실 수 있습니다 ** ** 도움이 필요합니다. 이는 문제를 찾는 데 도움이되는 귀중한 디버깅 기술입니다. 클라이언트 쪽에서 –