最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++自定義封裝socket操作業(yè)務類完整實例

 更新時間:2017年08月30日 11:37:19   作者:sauphy  
這篇文章主要介紹了C++自定義封裝socket操作業(yè)務類,結(jié)合完整實例形式分析了Linux環(huán)境下C++操作socket的封裝業(yè)務類,可實現(xiàn)基本的socket連接、參數(shù)設置、發(fā)送請求等基本功能,需要的朋友可以參考下

本文實例講述了C++自定義封裝socket操作業(yè)務類。分享給大家供大家參考,具體如下:

Linux下C++封裝socket操作的工具類(自己實現(xiàn))

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++程序設計有所幫助。

相關(guān)文章

  • C++超詳細講解樹與二叉樹

    C++超詳細講解樹與二叉樹

    在之前的文章里,我們學習的一直是一對一的線性結(jié)構(gòu),可現(xiàn)實中,還有很多一對多的情況需要處理,所以我們需要研究這樣一種一對多的數(shù)據(jù)結(jié)構(gòu)——樹
    2022-05-05
  • VC中實現(xiàn)GB2312、BIG5、Unicode編碼轉(zhuǎn)換的方法

    VC中實現(xiàn)GB2312、BIG5、Unicode編碼轉(zhuǎn)換的方法

    這篇文章主要介紹了VC中實現(xiàn)GB2312、BIG5、Unicode編碼轉(zhuǎn)換的方法,該功能非常實用,需要的朋友可以參考下
    2014-07-07
  • MFC創(chuàng)建模態(tài)對話框和非模態(tài)對話框的方法

    MFC創(chuàng)建模態(tài)對話框和非模態(tài)對話框的方法

    這篇文章主要介紹了MFC創(chuàng)建模態(tài)對話框和非模態(tài)對話框的方法,需要的朋友可以參考下
    2014-07-07
  • C++內(nèi)嵌匯編示例詳解

    C++內(nèi)嵌匯編示例詳解

    這篇文章主要介紹了C++內(nèi)嵌匯編,本文的所有代碼是在我自己的VS2008中測試的,由于環(huán)境的差別,不能保證能在所有的編譯器上運行,需要的朋友可以參考下
    2022-01-01
  • C++ socket實現(xiàn)miniFTP

    C++ socket實現(xiàn)miniFTP

    這篇文章主要為大家詳細介紹了C++ socket實現(xiàn)miniFTP的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • linux下使用g++編譯cpp工程的方法

    linux下使用g++編譯cpp工程的方法

    這篇文章主要介紹了linux下使用g++編譯cpp工程的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • C語言數(shù)字圖像處理之直方圖均衡化

    C語言數(shù)字圖像處理之直方圖均衡化

    這篇文章主要為大家詳細介紹了C語言數(shù)字圖像處理之直方圖均衡化,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 插入排序算法之希爾排序+直接插入排序

    插入排序算法之希爾排序+直接插入排序

    這篇文章主要介紹了插入排序算法之希爾排序+直接插入排序的相關(guān)知識,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-11-11
  • c++中strcpy函數(shù)在VS2015無法使用的問題

    c++中strcpy函數(shù)在VS2015無法使用的問題

    這篇文章主要介紹了c++中strcpy函數(shù)在VS2015無法使用的問題,具有一定的參考價值,有需要的可以了解一下。
    2016-11-11
  • C語言實現(xiàn)簡單學生管理系統(tǒng)

    C語言實現(xiàn)簡單學生管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)簡單學生管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論

罗定市| 大连市| 武宁县| 神木县| 本溪市| 玛纳斯县| 温州市| 广德县| 芜湖县| 房产| 楚雄市| 新民市| 河源市| 肥东县| 汨罗市| 天长市| 汉川市| 保亭| 山东省| 衡山县| 凤翔县| 永德县| 揭阳市| 西平县| 汉源县| 宜宾县| 琼海市| 潜山县| 法库县| 海晏县| 平顶山市| 确山县| 普兰店市| 东明县| 左权县| 绥德县| 香格里拉县| 安乡县| 清苑县| 十堰市| 澎湖县|