C++自定义封装socket操作业务类完整实例
发布时间:2020-12-24 19:44:53 所属栏目:经验 来源:网络整理
导读:本篇章节讲解C++自定义封装socket操作业务类。供大家参考研究具体如下: Linux下C++封装socket操作的工具类(自己实现) socketconnector.h #ifndef SOCKETCONNECTOR_H#define SOCKETCONNECTOR_H#include "global.h"using namespace std;class Soc
本篇章节讲解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 failn"); } if(setsockopt(m_sockFd,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,TCP_KEEPINTVL,(void *)&keepinterval,sizeof(keepinterval )) == -1) { printf("setsockopt TCP_KEEPINTVL failn"); } if(setsockopt(m_sockFd,TCP_KEEPCNT,(void *)&keepcount,sizeof(keepcount )) == -1) { printf("setsockopt TCP_KEEPCNT failn"); } 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:%dn",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 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++程序设计有所帮助。 (编辑:好传媒网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |