程序笔记   发布时间:2022-05-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了C++自定义封装socket操作业务类完整实例大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

本文实例讲述了C++自定义封装socket操作业务类。分享给大家供大家参,具体如下:

linux下C++封装socket操作的工具类(自己实现)

socketconnector.h

#ifndef SOCKETCONNECTOR_H
#define SOCKETCONNECTOR_H
#include "global.h"
using namespace std;
class SocketConnector
{
public:
  typedef enum {
    Enormal,EOther,} SocketState;
public:
  static SocketConnector * geTinstance();
  inline SocketState state(){ return m_state; }
  inline voID setState(SocketState _statE){  m_state = _state;  }
  inline bool isConnected() { return m_isConnected;  }
  inline voID setConnected(bool statE) { m_isConnected = state; }
  voID start();
  inline voID setServerIP(String ip){  m_server_ip = ip;}
  inline voID setServerPort(int port){ m_server_port = port; }
  int connect_sockfd();
  int onSendmessage(String & messagE);
private:
  SocketConnector();
  voID onConnectToServer(String & ip,int port);
  static void * onReportmessage(void * p);
  static void * onReadmessage(void * p);
  static void * onWritemessage(void * p);
private:
  SocketState m_state;
  bool m_isConnected;
  int m_sockFd;
  String m_server_ip;
  int m_server_port;
  pthread_t m_report_tID;
  pthread_t m_read_tID;
  pthread_t m_write_tID;
};
#endif // SOCKETCONNECTOR_H

socketconnector.cpp

#include "global.h"
#include "socketconnector.h"
#include "cmessagecenter.h"
#include "cmip_requestparser.h"
#include "csetTings.h"
#include "datadef.h"
#include "cStringutils.h"
using namespace std;
static SocketConnector * g_instance = NulL;
/**************************************************************************************************
*  Single Instance.
***************************************************************************************************/
SocketConnector * SocketConnector::geTinstance()
{
  if (g_instance == NulL)
  {
    g_instance = new SocketConnector();
  }
  return g_instance;
}
/**************************************************************************************************
*  Consturoctor
***************************************************************************************************/
SocketConnector::SocketConnector()
{
  m_isConnected = false;
  m_state = Enormal;
}
/**************************************************************************************************
*  Connect to Server By Blocking Method.
***************************************************************************************************/
voID SocketConnector::onConnectToServer(String & ip,int port){
  cout << __FUNCTION__ << "connecTing::[" << ip << "," << port << "]" << endl;
  struct timeval send_timeout;
  send_timeout.tv_sec = 5;
  send_timeout.tv_usec = 0;
  int keepalive = 1;
  int keepIDle = 10;
  int keepinterval = 5;
  int keepcount = 3;
  int value = 0;
  socklen_t len = sizeof(int);
  static struct sockaddr_in server_addr;
  memset(&server_addr,sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(port);
  server_addr.sin_addr.s_addr = inet_addr(ip.c_str());
  do
  {
    m_sockFd = socket(AF_INET,SOCK_STREAM,0);
    if ( -1 == m_sockFd )
    {
      sleep(1);
      conTinue;
    }
  }while(-1 == m_sockFd);
  if(setsockopt(m_sockFd,Sol_SOCKET,SO_SNDTIMEO,&send_timeout,sizeof(send_timeout)) == -1)
  {
    printf("setsockopt SO_SNDTIMEO fail\n");
  }
  if(setsockopt(m_sockFd,SO_KEEPAliVE,(void *)&keepalive,sizeof(keepalive )) == -1)
  {
    printf("setsockopt SO_KEEPAliVE fail\n");
  }
  if(setsockopt(m_sockFd,Sol_TCP,TCP_KEEPIDLE,(void*)&keepIDle,sizeof(keepIDle )) == -1)
  {
    printf("setsockopt TCP_KEEPIDLE fail\n");
  }
  if(setsockopt(m_sockFd,TCP_KEEPINTVL,(void *)&keepinterval,sizeof(keepinterval )) == -1)
  {
    printf("setsockopt TCP_KEEPINTVL fail\n");
  }
  if(setsockopt(m_sockFd,TCP_KEEPCNT,(void *)&keepcount,sizeof(keepcount )) == -1)
  {
    printf("setsockopt TCP_KEEPCNT fail\n");
  }
  getsockopt(m_sockFd,(void *)&value,&len);
  cout << __FUNCTION__ << "sockFd KeepIntval::[" << value << endl;
  while (!m_isConnected)
  {
    if(connect(m_sockFd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == 0)
    {
      m_isConnected = true;
      break;
    }
    else
    {
      if ( ECONNREFUSED == errno)
      {
        m_isConnected = false;
        sleep(1);
        printf("Reconnect To Server:%s Port:%d\n",m_server_ip.c_str(),m_server_port);
      }
      else
      {
        m_isConnected = false;
        perror("connected() error()");
        exit(-1);
      }
    }
  }
}
/**************************************************************************************************
*  Create Report Thread;
*  Create Read Thread;
*  Create Write Thread;
*  MainThread wait the subThreads exits;
***************************************************************************************************/
voID SocketConnector::start()
{
  m_sockFd = connect_sockfd();
  cout << __FUNCTION__ << "Will Create Report|Read|Write Thread." << endl;
  pthread_create(&m_report_tID,NulL,onReportmessage,this);  /* report to cmdmodule*/
  pthread_create(&m_read_tID,onReadmessage,this);  /* read from cmdmodule*/
  pthread_create(&m_write_tID,onWritemessage,this);  /* reply to cmdmodule*/
  pthread_join(m_read_tID,null);
  pthread_join(m_write_tID,null);
  pthread_join(m_report_tID,null);
}
/**************************************************************************************************
*  Used to Get connected socket fd.
*  if connected,return directly.
*  if not connected,try to create connect fd.
***************************************************************************************************/
int SocketConnector::connect_sockfd()
{
  if ( m_isConnected == truE)
  {
    cout << __FUNCTION__ << "::Socket is Already Connected." << endl;
    return m_sockFd;
  }
  cout << __FUNCTION__ << "::Will Try to Connect to Server." << endl;
  onConnectToServer(m_server_ip,m_server_port);
  return m_sockFd;
}
/**************************************************************************************************
*  Report Status to CmdModule Thread.
*  every 2s,report one message to cmDWifi.
***************************************************************************************************/
void * SocketConnector::onReportmessage(void * p)
{
  SocketConnector * connector = (SocketConnector *)(p);
  if ( NulL == p)
  {
    cout << __FUNCTION__ << "onSELEctSocket() Error: param [connector] is NulL" << endl;
    return NulL;
  }
  String content;
  int devType = atoi(CSetTings::geTinstance()->getKuType().c_str());
  int report_interval = atoi(CSetTings::geTinstance()->getKuReporTinterval().c_str());
  String position = CSetTings::geTinstance()->getKuposition();
  String local_ip = CSetTings::geTinstance()->getKuAgentip();
  cout << endl;
  cout << "###################################" << endl;
  cout << "Local-IP::" << local_ip << endl;
  cout << "Ku-CMA-Pos::" << position << endl;
  cout << "Ku-CMA-Type::" << devType << endl;
  cout << "###################################" << endl;
  cout << endl;
  while(true)
  {
    int state = connector->state();
    content = "<status>" + CStringUtils::toString(statE) + "</status>";
    content += "<type>" + CStringUtils::toString(devTypE) + "</type>";
    content += "<site>" + position + "</site>";
    content += "<ip>" + local_ip + "</ip>";
    Response resp(STATUS_REPORT_CMD,String(content));
    cmessageCenter::geTinstance()->addReply(resp);
    sleep(report_interval);
  }
}
/**************************************************************************************************
*  Read message from Connection.
*  Then Send message to messageCenter Queue.
***************************************************************************************************/
void * SocketConnector::onReadmessage(void * p)
{
  SocketConnector * connector = (SocketConnector *)(p);
  if ( NulL == p)
  {
    cout << __FUNCTION__ << "onSELEctSocket() Error: param [connector] is NulL" << endl;
    return NulL;
  }
  int sockFd = connector->connect_sockfd();
  fd_set fds;
  struct timeval timeout={0,0};
  const int BUFFER_LEN = 4*1024;
  static char buffer[BUFFER_LEN]={0};
  while(true)
  {
    FD_ZERO(&fds);
    FD_SET(sockFd,&fds);
    int ret = SELEct(sockFd + 1,&fds,&timeout);
    switch (ret) {
      case -1:/*Error process*/
      {
        perror("SELEct()");
        if ( EBADF == errno)
        {
          close(sockFd);
          connector->setConnected(false);
          sleep(1);
          sockFd = connector->connect_sockfd();
          conTinue;
        }
        if ( EINTR == errno || ENOMEM == errno)
        {
          sleep(1);
          conTinue;
        }
      }break;
      case 0:
      {
        //cout << "SELEct() timeout! " << endl;
      }break;
      default:
      {
        if(FD_ISSET(sockFd,&fds))
        {
          memset(buffer,BUFFER_LEN);
          int nRead = read(sockFd,buffer,BUFFER_LEN);
          cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
          cout << "From Server RecevIEd Data::" << String(buffer) << endl;
          cout << "From Server RecevIEd Length::" << nRead << endl;
          cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
          CrequestParser parser;
          request req;
          int ret = parser.parsetomessage(buffer,&req);
          if (0 != ret)
          {
            cout << __FUNCTION__ << "request Format is invalID" << endl;
            conTinue;
          }
          req.print();
          cmessageCenter::geTinstance()->addrequest(req);
        }
      }break;
    }
  }
}
/**************************************************************************************************
*  Write message to Connection.
*  Then Send message to messageCenter Queue.
***************************************************************************************************/
void * SocketConnector::onWritemessage(void * p)
{
  SocketConnector * connector = (SocketConnector *)(p);
  if ( NulL == p)
  {
    cout << __FUNCTION__ << "onSELEctSocket() Error: param [connector] is NulL" << endl;
    return NulL;
  }
  while (true)
  {
      Response msg;
      cmessageCenter::geTinstance()->getReplymsg(msg);
      String data = cmessageEncoder(msg).encode();
      connector->onSendmessage(data);
  }
}
/**************************************************************************************************
*  Send message By Socket.
***************************************************************************************************/
int SocketConnector::onSendmessage(String & strSend)
{
  if (atoi(CSetTings::geTinstance()->getDeBUGMode().c_str()) == 1)
  {
    cout << __FUNCTION__ << "Send To CmDWifi Data::" << endl;
    cout << strSend << endl;
  }
  int sock = m_sockFd;
  char *PDAta = &strSend[0];
  int nLen = static_cast<int>(strSend.size());
  int n@R_746_10586@l = nLen;
  int i = 0;
  while(1)
  {
    int nTmp = send(sock,&PDAta[i],n@R_746_10586@l,0);
    if (nTmp <= 0)
    {
      close(sock);
      return -1;
    }
    n@R_746_10586@l -= nTmp;
    i += nTmp;
    if (n@R_746_10586@l <= 0)
    {
      break;
    }
  }
  return 0;
}

希望本文所述对大家C++程序设计有所帮助。

大佬总结

以上是大佬教程为你收集整理的C++自定义封装socket操作业务类完整实例全部内容,希望文章能够帮你解决C++自定义封装socket操作业务类完整实例所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:socket