美文网首页
ROS-I simple_message 源码分析:UdpSer

ROS-I simple_message 源码分析:UdpSer

作者: play_robot | 来源:发表于2019-03-22 17:56 被阅读0次

udp_server类实现的是一个UDP服务器,继承自UdpSocket

namespace industrial
{
namespace udp_server
{

class UdpServer : public industrial::udp_socket::UdpSocket
{
public:

  UdpServer();
  ~UdpServer();

  bool makeConnect();
  bool init(int port_num);
};
init
bool UdpServer::init(int port_num)
{
  int rc = this->SOCKET_FAIL;
  bool rtn;
  SOCKLEN_T addrSize = 0;

  /* 创建socket:
   * AF_INET - IPv4 协议
   * SOCK_DGRAM - UDP 类型
   * protocol (0) - 采用默认
   */
  rc = SOCKET(AF_INET, SOCK_DGRAM, 0);
  if (this->SOCKET_FAIL != rc)
  {
    this->setSockHandle(rc);
    LOG_DEBUG("Socket created, rc: %d", rc);
    LOG_DEBUG("Socket handle: %d", this->getSockHandle());

    // Initialize address data structure
    memset(&this->sockaddr_, 0, sizeof(this->sockaddr_));
    this->sockaddr_.sin_family = AF_INET;
    this->sockaddr_.sin_addr.s_addr = INADDR_ANY;
    this->sockaddr_.sin_port = HTONS(port_num);

    addrSize = sizeof(this->sockaddr_);
    rc = BIND(this->getSockHandle(), (sockaddr *)&(this->sockaddr_), addrSize);

    if (this->SOCKET_FAIL != rc)
    {
      rtn = true;
      LOG_INFO("Server socket successfully initialized");
    }
    else
    {
      LOG_ERROR("Failed to bind socket, rc: %d", rc);
      CLOSE(this->getSockHandle());
      rtn = false;
    }
  }
  else
  {
    LOG_ERROR("Failed to create socket, rc: %d", rc);
    rtn = false;
  }
  return rtn;
}

初始化过程和TcpServer类似,依次调用socket,bind,但无需进入监听状态。

makeConnect
bool UdpServer::makeConnect()
{
  ByteArray send;
  char sendHS = this->CONNECT_HANDSHAKE;
  char recvHS = 0;
  int bytesRcvd = 0;
  const int timeout = 1000;  // Time (ms) between handshake sends
  bool rtn = false;
  
  send.load((void*)&sendHS, sizeof(sendHS));
    
  if (!this->isConnected())
  {
    this->setConnected(false);
    
    // 循环,监听握手号
    do
    {
      ByteArray recv;
      recvHS = 0;
      if (this->isReadyReceive(timeout))
      {
        bytesRcvd = this->rawReceiveBytes(this->buffer_, 0);
        
        if (bytesRcvd > 0)
        {
          LOG_DEBUG("UDP server received %d bytes while waiting for handshake", bytesRcvd);
          recv.init(&this->buffer_[0], bytesRcvd);
          recv.unload((void*)&recvHS, sizeof(recvHS));
        }
      }
      
    }
    while(recvHS != sendHS);
    
    const int sendLen = send.getBufferSize();
    char      localBuffer[sendLen];
    send.unload(localBuffer, sendLen);

    // 回复握手号
    this->rawSendBytes(localBuffer, sendLen);
    this->setConnected(true);
    rtn = true;
    
  }
  else
  {
    LOG_WARN("Tried to connect when socket already in connected state");
    rtn = true;
  }

  return rtn;
}

调用makeConnect后,若当前没有连接,服务器会进入循环,尝试接收客户端发送握手号,接收到握手号后服务器则回复相同的握手号。

相关文章

网友评论

      本文标题:ROS-I simple_message 源码分析:UdpSer

      本文链接:https://www.haomeiwen.com/subject/ttbrvqtx.html