端点上的数据损坏

时间:2011-03-24 13:33:54

标签: boost-asio

在循环调用中,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_

2 个答案:

答案 0 :(得分:2)

您的示例不显示顶级用法,线程等。

检查是否同时从不同的线程发送到同一个套接字,这可能是个问题。按顺序执行

答案 1 :(得分:0)

在这种情况下,数据损坏很可能是因为您正在使用async_read,并且在async_read处理程序中,再次调用async_read(在处理程序之后没有时间进行清理)。

相关:boost::asio : data corruption