eos/plugins/net_plugin/net_plugin.cpp:
//写地址的弱连接
connection_wptr weak_conn = conn
fc::optional<std::size_t> outstanding_read_bytes;
boost::asio::async_read(*conn->socket,
//待处理消息缓冲区,完成处理器
conn->pending_message_buffer.get_buffer_sequence_for_boost_async_read(), completion_handler,
[this,weak_conn]( boost::system::error_code ec, std::size_t bytes_transferred ) {
auto conn = weak_conn.lock();
if (!conn) {
return;
}
conn->outstanding_read_bytes.reset();
try {
//没有错误
if( !ec ) {
//传输的字节数 > 连接中写入的字节数
if (bytes_transferred > conn->pending_message_buffer.bytes_to_write()) {
//log显示,异步读取回调:显示传输字节数 、缓冲区待处理消息要写入的字节数
elog("async_read_some callback: bytes_transfered = ${bt}, buffer.bytes_to_write = ${btw}",
("bt",bytes_transferred)("btw",conn->pending_message_buffer.bytes_to_write()));
}
EOS_ASSERT(bytes_transferred <= conn->pending_message_buffer.bytes_to_write(), plugin_exception, "");
//高优先级写入缓冲区待处理消息
conn->pending_message_buffer.advance_write_ptr(bytes_transferred);
while (conn->pending_message_buffer.bytes_to_read() > 0) {
uint32_t bytes_in_buffer = conn->pending_message_buffer.bytes_to_read();
//缓冲区中的字节数<消息头的大小
if (bytes_in_buffer < message_header_size) {
//将不在缓冲区中的字节数插入读取的字节数
conn->outstanding_read_bytes.emplace(message_header_size - bytes_in_buffer);
break;
} else {
uint32_t message_length;
//待处理消息缓冲区的索引
auto index = conn->pending_message_buffer.read_index();
conn->pending_message_buffer.peek(&message_length, sizeof(message_length), index);
//消息长度>定义的发送缓冲区大小的2倍 或 消息长度为0,则报传入消息长度异常的错误:消息长度、远程断点,关闭连接
if(message_length > def_send_buffer_size*2 || message_length == 0) {
boost::system::error_code ec;
elog("incoming message length unexpected (${i}), from ${p}", ("i", message_length)("p",boost::lexical_cast<std::string>(conn->socket->remote_endpoint(ec))));
close(conn);
return;
}
//消息总字节数=消息长度+消息头大小
auto total_message_bytes = message_length + message_header_size;
//缓冲区字节数>=消息总字节数
if (bytes_in_buffer >= total_message_bytes) {
//此连接的缓冲区待处理消息,优先读取消息头
conn->pending_message_buffer.advance_read_ptr(message_header_size);
//如果处理此连接进程的下一条消息为false,即消息全部处理完,返回
if (!conn->process_next_message(*this, message_length)) {
return;
}
} else {
//剩余的消息字节数=消息总字节数-缓冲区的字节数
auto outstanding_message_bytes = total_message_bytes - bytes_in_buffer;
//缓冲区可用的字节数=此连接缓冲区待处理消息可以写入的字节数
auto available_buffer_bytes = conn->pending_message_buffer.bytes_to_write();
//剩余消息的字节数大于缓冲区可用字节数,待处理消息缓冲区增加(剩余字节数-缓冲区可用字节数)的大小
if (outstanding_message_bytes > available_buffer_bytes) {
conn->pending_message_buffer.add_space( outstanding_message_bytes - available_buffer_bytes );
}
//读入的字节数中插入剩余消息的字节数
conn->outstanding_read_bytes.emplace(outstanding_message_bytes);
break;
}
}
}
//开始读取此连接的消息
start_read_message(conn);
} else {
//panme:连接中对等节点名字
auto pname = conn->peer_name();
//判断消息是否都读取完
if (ec.value() != boost::asio::error::eof) {
elog( "Error reading message from ${p}: ${m}",("p",pname)( "m", ec.message() ) );
} else {
ilog( "Peer ${p} closed connection",("p",pname) );
}
close( conn );
}
}
//连接中没有这个对等节点的异常
catch(const std::exception &ex) {
string pname = conn ? conn->peer_name() : "no connection name";
elog("Exception in handling read data from ${p} ${s}",("p",pname)("s",ex.what()));
close( conn );
}
catch(const fc::exception &ex) {
string pname = conn ? conn->peer_name() : "no connection name";
elog("Exception in handling read data ${s}", ("p",pname)("s",ex.to_string()));
close( conn );
}
//处理其他任何异常的代码。
catch (...) {
string pname = conn ? conn->peer_name() : "no connection name";
elog( "Undefined exception hanlding the read data from connection ${p}",( "p",pname));
close( conn );
}
} );
} catch (...) {
string pname = conn ? conn->peer_name() : "no connection name";
elog( "Undefined exception handling reading ${p}",("p",pname) );
close( conn );
}
}