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, 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操作业务类完整实例

相关文章:

你感兴趣的文章:

标签云: