enet学习(二):enet_peer_send()函数

/** Queues a packet to be sent.
    @param peer destination for the packet
    @param channelID channel on which to send
    @param packet packet to send
    @retval 0 on success
    @retval < 0 on failure
*/
int
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
{
   ENetChannel * channel = & peer -> channels [channelID];
   ENetProtocol command;
   size_t fragmentLength;
 
   if (peer -> state != ENET_PEER_STATE_CONNECTED ||
       channelID >= peer -> channelCount ||
       packet -> dataLength > peer -> host -> maximumPacketSize)
     return -1;
 
   fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
   if (peer -> host -> checksum != NULL)
     fragmentLength -= sizeof(enet_uint32);
 
   if (packet -> dataLength > fragmentLength)
   {
      enet_uint32 fragmentCount = (packet -> dataLength + fragmentLength - 1) / fragmentLength,
             fragmentNumber,
             fragmentOffset;
      enet_uint8 commandNumber;
      enet_uint16 startSequenceNumber; 
      ENetList fragments;          //命令队列
      ENetOutgoingCommand * fragment; //命令队列顶部的即将被使用的命令
 
      if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT)
        return -1;
      if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT &&
          channel -> outgoingUnreliableSequenceNumber < 0xFFFF)
      {
         commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT;
         startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
      }
      else
      {
         commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
         startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
      }
        
      enet_list_clear (& fragments);
 
      for (fragmentNumber = 0,                                      //逐条命令执行存放
             fragmentOffset = 0;
           fragmentOffset < packet -> dataLength;
           ++ fragmentNumber,
             fragmentOffset += fragmentLength)
      {
         if (packet -> dataLength - fragmentOffset < fragmentLength)
           fragmentLength = packet -> dataLength - fragmentOffset;
   
         //如果当前命令为空,而命令列表中非空,就把当前命令移除命令列表,表示当前命令无效。然后再插入新的有效命令。
         fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
         if (fragment == NULL)
         {
            while (! enet_list_empty (& fragments))
            {
               fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
               
               enet_free (fragment);
            }
            
            return -1;
         }
        fragment -> fragmentOffset = fragmentOffset;
         fragment -> fragmentLength = fragmentLength;
         fragment -> packet = packet;
         fragment -> command.header.command = commandNumber;
         fragment -> command.header.channelID = channelID;
         fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
         fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
         fragment -> command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32 (fragmentCount);
         fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
         fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
         fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
        
         enet_list_insert (enet_list_end (& fragments), fragment);
      }
 
      packet -> referenceCount += fragmentNumber;
 
      while (! enet_list_empty (& fragments))
      {
         fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
 
         enet_peer_setup_outgoing_command (peer, fragment);
      }
 
      return 0;
   }   //if (packet -> dataLength > fragmentLength) over
 
   command.header.channelID = channelID;
   //根据FLAG的标志,设置发送包协议的格式。
   if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
      command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }
   else 
   if (packet -> flags & ENET_PACKET_FLAG_RELIABLE || channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }
else
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
      command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }
 
   if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
     return -1;
 
   return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值