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操作业务类完整实例 的全部内容, 来源链接: utcz.com/z/344729.html

回到顶部