C++自定義封裝socket操作業(yè)務(wù)類完整實(shí)例
本文實(shí)例講述了C++自定義封裝socket操作業(yè)務(wù)類。分享給大家供大家參考,具體如下:
Linux下C++封裝socket操作的工具類(自己實(shí)現(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; }
希望本文所述對(duì)大家C++程序設(shè)計(jì)有所幫助。
上一篇:C++ 中const對(duì)象與const成員函數(shù)的實(shí)例詳解
欄 目:C語(yǔ)言
下一篇:C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之中綴樹(shù)轉(zhuǎn)后綴樹(shù)的實(shí)例
本文標(biāo)題:C++自定義封裝socket操作業(yè)務(wù)類完整實(shí)例
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1218.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子