net_plugin.cpp--async_read解析

本文深入探讨了EOS网络插件net_plugin.cpp中的async_read实现,解析了其在区块同步和节点通信中的关键作用,帮助读者理解EOS节点间数据交互的底层机制。
摘要由CSDN通过智能技术生成

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 );
      }
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值