簡介:C++ boost asio |同步寫入異步讀取|無法在第二次收到正確的數據讀取
我想用C++做一個服務器/客戶端應用程序和boost :: ASIO,我也想使同步在對方收到寫入以連續的異步讀取結束。 例如我的服務器異步讀取固定字節長度的數據流,然後移動到由客戶端同步寫入發送的下一個字節。
問題:
在連續異步讀取字節被正確地讀出的第一個流,但是當它繼續到下一個異步讀的東西從另一端發送具有相同字節長度我excpecting但它是垃圾或我不能將其轉換爲有價值的數據。
驗證碼:
private:
static const int MAX_MTU = 1500; //Ethernet Maximum Transfer UNIT (MTU)...
static const int TRASH_CAN = 100; //Amount to substract from the MAX_MTU to make room for basic packet structure elements.
static const int BUFFER_SIZE = MAX_MTU - TRASH_CAN;
boost::mutex mutex;
typedef char* data_bytes;
std::list<data_bytes> data;
private:
tcp::socket socket_;
boost::asio::io_service& io_service_;
moqane::tcp_packet *packet_;
// CTOR for the incoming connection from a client to the server
public: tcp_session(boost::asio::io_service& io_service)
: io_service_(io_service),
socket_(io_service),
packet_(new moqane::tcp_packet())
{
// ......
}
// CTOR for the outgoing clinet connection to the server...
public: tcp_session(boost::asio::io_service& io_service, tcp::resolver::iterator endpoint_iterator)
: io_service_(io_service),
socket_(io_service),
packet_(new moqane::tcp_packet())
{
boost::asio::async_connect(socket_,
endpoint_iterator,
boost::bind(&tcp_session::connect_to_server_hndlr,
this,
boost::asio::placeholders::error)
);
}
tcp::socket& socket()
{
return socket_;
}
public:
void read_header()
{
read_packet(packet_->HEADER_LENGTH,
boost::bind(
&moqane::tcp_session::read_header_hndlr,
shared_from_this(),
packet_->HEADER_LENGTH,
boost::asio::placeholders::error)
);
}
private:
void connect_to_server_hndlr(const boost::system::error_code& error)
{
if (!error)
{
read_header();
}
else
{
// TODO: fire the error event...
}
}
private:
template <class T>
void read_packet(int packet_length, T handler)
{
/*
Packet Structure: (Mohamed Tarek (moqane))
==============================================================================================
HEADER: could be a 3 or 4 bytes that give enough information to the endpoint on how to receive
those bytes.
SIZE : A 4 byte-length number that tell the endpoint how much data in bytes ar comming.
ex: 0340 which should tell us that the incoming data are 340 bytes, so we will not
receive more or less than that.
DATA : the incoming valuable information that we want to receive in the first place.
---------------------------------------------
| | | |
| HEADER | SIZE | DATA... | ----> PACKET
| 3b | 4b | N/A b |
----------------------------------------------
==============================================================================================
*/
if (data.size() > 0)
{
data.clear();
}
char d[moqane::tcp_session::BUFFER_SIZE];
data.push_back(d);
boost::asio::async_read(socket_,
boost::asio::buffer(data.back(), packet_length),
handler
);
}
private:
void write_packet(char* data_bytes)
{
boost::asio::write(socket_, boost::asio::buffer(data_bytes, sizeof(data_bytes)));
}
private:
void write_packet_hndlr(const boost::system::error_code& error)
{
if (!error)
{
}
else
{
}
}
private:
void read_header_hndlr(int packet_length, const boost::system::error_code& error)
{
if (!error)
{
// convert bytes to wxstring
// wxString s = moqane::wx2string::To_wxString(packet_->DATA(), packet_->HEADER_LENGTH());
// convert our bytes to string
std::string header(data.back(), packet_length);
if (packet_->is_header(header))
{
// read the SIZE packet
read_packet(packet_->SIZE_LENGTH,
boost::bind(
&moqane::tcp_session::read_size_hndlr,
shared_from_this(),
packet_->SIZE_LENGTH,
header,
"",
boost::asio::placeholders::error)
);
}
else
{
// reread the HEADER packet if it's not a valid header
read_header();
}
}
else
{
// TODO: fire the error event...
}
}
private:
void read_size_hndlr(int packet_length, std::string header, std::string info, const boost::system::error_code& error)
{
if (!error)
{
std::string str_length(data.back(), packet_length);
int next_packet_length = moqane::number2string::ToInt(str_length);
if (next_packet_length > 0)
{
if (header == packet_->HEADER_STRING)
{
read_packet(next_packet_length,
boost::bind(
&moqane::tcp_session::read_STRING_hndlr,
shared_from_this(),
next_packet_length,
boost::asio::placeholders::error)
);
}
else if (header == packet_->HEADER_COMMAND)
{
}
else
{
// reread the HEADER packet if it's not a valid header
read_header();
}
}
else
{
// reread the HEADER packet if it's not a valid size
read_header();
}
}
else
{
// TODO: fire the error event...
}
}
private:
void read_STRING_hndlr(int packet_length, const boost::system::error_code& error)
{
std::string std_str(data.back(), packet_length);
std::string v = "";
}
public:
void write_STRING(char* string_data)
{
boost::mutex::scoped_lock lock(mutex);
{
write_packet(moqane::number2string::To_CharArray("STR"));
write_packet(moqane::number2string::To_CharArray("xxx1"));
write_packet(moqane::number2string::To_CharArray("a"));
}
}
};
我現在就嘗試,讓你知道,謝謝。 – 2013-02-22 17:49:09
對不起,當我把'char data [BUFFER_SIZE];'作爲全局變量時,第二次讀取(在'read_size_hndlr')接收垃圾字節或一些不可讀的字符,並且返回的字符串總是空的。 – 2013-02-22 17:57:01
問題解決了它是由於'packet_length'由'sizeof'獲得錯誤的字符長度*造成的。 – 2013-02-22 23:51:02