C++自定义封装socket操作业务类完整实例

发布时间 - 2026-01-11 03:01:56    点击率:

本文实例讲述了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, 0, 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, SOL_SOCKET, 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, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval )) == -1)
  {
    printf("setsockopt TCP_KEEPINTVL fail\n");
  }
  if(setsockopt(m_sockFd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount )) == -1)
  {
    printf("setsockopt TCP_KEEPCNT fail\n");
  }
  getsockopt(m_sockFd, SOL_TCP, TCP_KEEPINTVL, (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, NULL, onReadMessage, this);  /* read from cmdmodule*/
  pthread_create(&m_write_tid, NULL, 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,0,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,NULL,NULL,&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, 0, 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 nTotal = nLen;
  int i = 0;
  while(1)
  {
    int nTmp = send(sock, &pData[i], nTotal, 0);
    if (nTmp <= 0)
    {
      close(sock);
      return -1;
    }
    nTotal -= nTmp;
    i += nTmp;
    if (nTotal <= 0)
    {
      break;
    }
  }
  return 0;
}

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


# C++  # 自定义  # 封装  # socket类  # 浅谈C++ Socket编程  # C++ 中 socket编程实例详解  # C++中Socket网络编程实例详解  # C++ socket实现miniFTP  # C++用winapi socket实现局域网语音通话功能  # 给大家  # 所述  # 程序设计  # 讲述了  # connecting  # endl  # struct  # Method  # cout  # lt  # keepalive  # keepidle  # tv_usec  # timeval  # send_timeout  # tv_sec  # Blocking  # datadef  # cstringutils 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  三星、SK海力士获美批准:可向中国出口芯片制造设备  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  在线制作视频的网站有哪些,电脑如何制作视频短片?  Laravel如何使用Blade模板引擎?(完整语法和示例)  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  javascript中的try catch异常捕获机制用法分析  做企业网站制作流程,企业网站制作基本流程有哪些?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  EditPlus中的正则表达式 实战(2)  如何用5美元大硬盘VPS安全高效搭建个人网站?  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  SQL查询语句优化的实用方法总结  如何在万网ECS上快速搭建专属网站?  文字头像制作网站推荐软件,醒图能自动配文字吗?  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  Linux安全能力提升路径_长期防护思维说明【指导】  Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  香港服务器WordPress建站指南:SEO优化与高效部署策略  如何快速生成可下载的建站源码工具?  如何在不使用负向后查找的情况下匹配特定条件前的换行符  Firefox Developer Edition开发者版本入口  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  如何在阿里云虚拟主机上快速搭建个人网站?  如何在万网开始建站?分步指南解析  Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  Laravel如何使用Eloquent进行子查询  音响网站制作视频教程,隆霸音响官方网站?  Python进程池调度策略_任务分发说明【指导】  如何在IIS7中新建站点?详细步骤解析  Laravel怎么连接多个数据库_Laravel多数据库连接配置  如何在局域网内绑定自建网站域名?  如何快速搭建支持数据库操作的智能建站平台?  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  如何为不同团队 ID 动态生成多个非值班状态按钮  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  电商网站制作价格怎么算,网上拍卖流程以及规则?  Android okhttputils现在进度显示实例代码  如何快速查询网址的建站时间与历史轨迹?  如何在企业微信快速生成手机电脑官网?  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  免费网站制作appp,免费制作app哪个平台好?  想要更高端的建设网站,这些原则一定要坚持!