刚连接上:调用async_accept
1 boost::shared_ptr<tcp::socket> spMySocket(new tcp::socket(m_ioservice)); 2 m_acceptor.async_accept(*spMySocket,boost::bind(&CService::accept_handle,this,spMySocket,_1));
接收到数据:
async_read将m_packet填满或者断开连接才会返回。
1 socket_.async_read_some(asio::buffer(&m_packet, sizeof(m_packet)), 2 boost::bind(&CServer::read_handle, shared_from_this(),_1));
async_read_some,读取到数据马上返回,不一定读完。
1 socket_.async_read_some(asio::buffer(&m_packet, sizeof(m_packet)), 2 boost::bind(&tcp_connection::HandleReadCardKey, shared_from_this(), 3 _1));
再是发送数据:使用async_write,要循环调用async_write发送数据时,一定要确保前面数据已经发送。
比如:以下是错误代码
1 for (int i=0; i < n; i++) 2 { 3 boost::asio::async_write( 4 socket_, 5 boost::asio::buffer( buffer[i].data_.get(), buffer[i].length_ ), 6 boost::asio::transfer_at_least(buffer[i].length_), 7 boost::bind( 8 &HttpServer::HandleTcpSend, 9 shared_from_this(), 10 boost::asio::placeholders::error, 11 boost::asio::placeholders::bytes_transferred 12 ) 13 ); 14 // Do something 15 }
如果在第一个async_write还没有发送完毕之后,从第二个async_write发送数据,势必导致接收端接收的数据有问题。这个并不是asio的限制,底层套接字的一些函数,如发送等也无法保证一次异步操作就把所有的数据都通过TCP流发送出去。async_write将被告知有多少字节实际发送了,然后要求在下一次异步操作时发送剩余的字节。async_write是通过一次或者多次调用async_write_some函数来实现的,那么如果在第一个async_write还没有完成就调用第二个async_write,async_write_some就有可能先将第二个buffer的数据先发送出去。
正确的代码是:
1 int i=0; 2 boost::asio::async_write( 3 socket_, 4 boost::asio::buffer( buffer[i].data_.get(), buffer[i].length_ ), 5 boost::asio::transfer_at_least(buffer[i].length_), 6 boost::bind( 7 &HttpServer::HandleTcpSend, 8 shared_from_this(), 9 boost::asio::placeholders::error, 10 boost::asio::placeholders::bytes_transferred 11 ) 12 ); 13 14 // Do something 15 16 void HttpServer::HandleTcpSend(const boost::system::error_code& err, 17 size_t bytes_transferred) 18 { 19 i++; 20 boost::asio::async_write( 21 socket_, 22 boost::asio::buffer( buffer[i].data_.get(), buffer[i].length_ ), 23 boost::asio::transfer_at_least(buffer[i].length_), 24 boost::bind( 25 &HttpServer::HandleTcpSend, 26 shared_from_this(), 27 boost::asio::placeholders::error, 28 boost::asio::placeholders::bytes_transferred 29 ) 30 ); 31 }