栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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;

SocketConnector * SocketConnector::getInstance()
{
  if (g_instance == NULL)
  {
    g_instance = new SocketConnector();
  }
  return g_instance;
}

SocketConnector::SocketConnector()
{
  m_isConnected = false;
  m_state = ENormal;
}

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 failn");
  }
  if(setsockopt(m_sockFd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive )) == -1)
  {
    printf("setsockopt SO_KEEPALIVE failn");
  }
  if(setsockopt(m_sockFd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle , sizeof(keepidle )) == -1)
  {
    printf("setsockopt TCP_KEEPIDLE failn");
  }
  if(setsockopt(m_sockFd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval )) == -1)
  {
    printf("setsockopt TCP_KEEPINTVL failn");
  }
  if(setsockopt(m_sockFd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount )) == -1)
  {
    printf("setsockopt TCP_KEEPCNT failn");
  }
  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:%dn", m_server_ip.c_str(), m_server_port);
      }
      else
      {
 m_isConnected = false;
 perror("connected() error()");
 exit(-1);
      }
    }
  }
}

void SocketConnector::start()
{
  m_sockFd = connect_sockfd();
  cout << __FUNCTION__ << "Will Create Report|Read|Write Thread." << endl;
  pthread_create(&m_report_tid,NULL, onReportMessage, this);  
  pthread_create(&m_read_tid, NULL, onReadMessage, this);  
  pthread_create(&m_write_tid, NULL, onWriteMessage, this);  
  pthread_join(m_read_tid,NULL);
  pthread_join(m_write_tid,NULL);
  pthread_join(m_report_tid,NULL);
}

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;
}

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 = "" + CStringUtils::toString(state) + "";
    content += "" + CStringUtils::toString(devType) + "";
    content += "" + position + "";
    content += "" + local_ip + "";
    Response resp(STATUS_REPORT_CMD,0,string(content));
    CMessageCenter::getInstance()->addReply(resp);
    sleep(report_interval);
  }
}

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:
      {
 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;
    }
  }
}

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);
  }
}

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(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++程序设计有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/63290.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号