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

ROS-I simple_message 源码分析:TcpSer

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

TcpServer类继承自TcpSocket,提供了server的初始化和连接功能。

namespace industrial
{
namespace tcp_server
{

class TcpServer : public industrial::tcp_socket::TcpSocket
{
public:

  TcpServer();
  ~TcpServer();

  bool init(int port_num);

  // Overrides
  bool makeConnect();

protected:

  int srvr_handle_;

  int getSrvrHandle() const
  {
    return srvr_handle_;
  }

  void setSrvrHandle(int srvr_handle_)
  {
    this->srvr_handle_ = srvr_handle_;
  }
};

} //simple_socket
} //industrial
init
bool TcpServer::init(int port_num)
{
  int rc;
  bool rtn;
  const int reuse_addr = 1;
  //int err;
  SOCKLEN_T addrSize = 0;

  rc = SOCKET(AF_INET, SOCK_STREAM, 0);
  if (this->SOCKET_FAIL != rc)
  {
    this->setSrvrHandle(rc);
    LOG_DEBUG("Socket created, rc: %d", rc);
    LOG_DEBUG("Socket handle: %d", this->getSrvrHandle());

    
    SET_REUSE_ADDR(this->getSrvrHandle(), reuse_addr);

    // 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->getSrvrHandle(), (sockaddr *)&(this->sockaddr_), addrSize);

    if (this->SOCKET_FAIL != rc)
    {
      LOG_INFO("Server socket successfully initialized");

      rc = LISTEN(this->getSrvrHandle(), 1);

      if (this->SOCKET_FAIL != rc)
      {
        LOG_INFO("Socket in listen mode");
        rtn = true;
      }
      else
      {
        LOG_ERROR("Failed to set socket to listen");
        rtn = false;
      }
    }
    else
    {
      LOG_ERROR("Failed to bind socket, rc: %d", rc);
      CLOSE(this->getSrvrHandle());
      rtn = false;
    }

  }
  else
  {
    LOG_ERROR("Failed to create socket, rc: %d", rc);
    rtn = false;
  }

  return rtn;
}

init方法用于TCP server的初始化,依次调用socket创建套接字,调用bind绑定地址,最后调用listen启动服务端的监听,等待客户端的连接请求。
this->setSrvrHandle(rc)用于将创建好的监听socket描述符保存至本地,以便将来恢复连接时使用。

makeConnect
bool TcpServer::makeConnect()
{
  bool rtn = false;
  int rc = this->SOCKET_FAIL;
  //int socket = this->SOCKET_FAIL;
  int disableNodeDelay = 1;
  int err = 0;

  if (!this->isConnected())
  {
    this->setConnected(false);
    if (this->SOCKET_FAIL != this->getSockHandle())
    {
      CLOSE(this->getSockHandle());
      this->setSockHandle(this->SOCKET_FAIL);
    }

    rc = ACCEPT(this->getSrvrHandle(), NULL, NULL);

    if (this->SOCKET_FAIL != rc)
    {
      this->setSockHandle(rc);
      LOG_INFO("Client socket accepted");

      // The set no delay disables the NAGEL algorithm
      rc = SET_NO_DELAY(this->getSockHandle(), disableNodeDelay);
      err = errno;
      if (this->SOCKET_FAIL == rc)
      {
        LOG_WARN("Failed to set no socket delay, errno: %d, sending data can be delayed by up to 250ms", err);
      }
      this->setConnected(true);
      rtn = true;
    }
    else
    {
      LOG_ERROR("Failed to accept for client connection");
      rtn = false;
    }
  }
  else
  {
    LOG_WARN("Tried to connect when socket already in connected state");
  }

  return rtn;

}

makeConnect用于接受客户端连接请求,由accept函数完成。并保存连接socket描述符,以备和客户端之间的发送接收时使用。至此,一个可用的TcpServer就完成了。

相关文章

网友评论

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

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