C++自定义封装socket操作业务类完整实例
发布时间 - 2026-01-11 03:01:56 点击率:次本文实例讲述了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类
# 浅谈C++ Socket编程
# C++ 中 socket编程实例详解
# C++中Socket网络编程实例详解
# C++ socket实现miniFTP
# C++用winapi socket实现局域网语音通话功能
# 给大家
# 所述
# 程序设计
# 讲述了
# connecting
# endl
# struct
# Method
# cout
# lt
# keepalive
# keepidle
# tv_usec
# timeval
# send_timeout
# tv_sec
# Blocking
# datadef
# cstringutils
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
三星、SK海力士获美批准:可向中国出口芯片制造设备
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
在线制作视频的网站有哪些,电脑如何制作视频短片?
Laravel如何使用Blade模板引擎?(完整语法和示例)
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
javascript中的try catch异常捕获机制用法分析
做企业网站制作流程,企业网站制作基本流程有哪些?
实现点击下箭头变上箭头来回切换的两种方法【推荐】
EditPlus中的正则表达式 实战(2)
如何用5美元大硬盘VPS安全高效搭建个人网站?
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
SQL查询语句优化的实用方法总结
如何在万网ECS上快速搭建专属网站?
文字头像制作网站推荐软件,醒图能自动配文字吗?
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Linux安全能力提升路径_长期防护思维说明【指导】
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布
香港服务器WordPress建站指南:SEO优化与高效部署策略
如何快速生成可下载的建站源码工具?
如何在不使用负向后查找的情况下匹配特定条件前的换行符
Firefox Developer Edition开发者版本入口
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解
如何在阿里云虚拟主机上快速搭建个人网站?
如何在万网开始建站?分步指南解析
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
Laravel如何使用Eloquent进行子查询
音响网站制作视频教程,隆霸音响官方网站?
Python进程池调度策略_任务分发说明【指导】
如何在IIS7中新建站点?详细步骤解析
Laravel怎么连接多个数据库_Laravel多数据库连接配置
如何在局域网内绑定自建网站域名?
如何快速搭建支持数据库操作的智能建站平台?
Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
如何为不同团队 ID 动态生成多个非值班状态按钮
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
电商网站制作价格怎么算,网上拍卖流程以及规则?
Android okhttputils现在进度显示实例代码
如何快速查询网址的建站时间与历史轨迹?
如何在企业微信快速生成手机电脑官网?
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
免费网站制作appp,免费制作app哪个平台好?
想要更高端的建设网站,这些原则一定要坚持!
上一篇:上海定制建站公司哪家专业更优?
下一篇:解决Linux系统内存问题
上一篇:上海定制建站公司哪家专业更优?
下一篇:解决Linux系统内存问题

