基于google protobuf 的 socket udp 通信
发布日期:2022-03-30 18:18:26 浏览次数:63 分类:博客文章

本文共 7428 字,大约阅读时间需要 24 分钟。

SocketClient.cpp

#include "SocketClient.h"#include "ClientInfoSave.h"#include "serverMsg.pb.h"using namespace Message;string SocketClient::m_strHeatMsg = ""; set
SocketClient::m_set_BaseView;int SocketClient::m_nHeatFailCount = 0;SocketClient::SocketClient(){}SocketClient::~SocketClient(){}SocketClient* SocketClient::instance(){ static SocketClient* pInstance =NULL; if(!pInstance) { pInstance = new SocketClient(); } return pInstance;}void SocketClient::insertBaseView(BaseView* pBaseView){ m_set_BaseView.insert(pBaseView);}void SocketClient::removeBaseView(BaseView *pBaseView){ m_set_BaseView.erase(pBaseView);}void SocketClient::sendTableMsgToServer(eEvent event , google::protobuf::MessageLite *msg){ sendMsgToServer(event , msg);}void SocketClient::sendMsgToServer(eEvent event ,google::protobuf::MessageLite *msg){ MsgBase msgBase; msgBase.set_eventid(event); msgBase.set_msg(msg->SerializeAsString()); string str = msgBase.SerializeAsString(); sendMsg(str);}void SocketClient::recvMsg(string msg){ MsgBase msgBase; msgBase.ParseFromString(msg); switch (msgBase.eventid()) { case eLogin: onLoginSucceess(msgBase.msg()); break; case eHeat: onHeat(); break; case eTable: recvTableMsg(msgBase.msg()); break; default: break; }}void SocketClient::reqLogin(){ Login login; login.set_userid(ClientInfoSave::instance()->getUserId()); MsgBase msgBase; msgBase.set_eventid(eLogin); msgBase.set_msg(login.SerializeAsString()); loginServer(msgBase.SerializeAsString());}void SocketClient::reqLeave(){ Leave leave; leave.set_userid(ClientInfoSave::instance()->getUserId()); sendMsgToServer(eLeave,&leave);}void* SocketClient::reqHeat(void *arg){ string msg = *((string*)arg); for(m_nHeatFailCount =0; m_nHeatFailCount<10 ; ) { sendMsg(msg); CCLog("sendheat count:%d",m_nHeatFailCount); ++m_nHeatFailCount; Sleep(1500); } onLoginFail(); return NULL;}void SocketClient::onLoginSucceess(string msg){ Login login; login.ParsePartialFromString(msg); ClientInfoSave::instance()->setUserId(login.userid()); CCLog(" longin success :%d", login.userid()); AnsHeatBeat heat; heat.set_userid(login.userid()); sendMsgToServer(eHeat,&heat); MsgBase msgBase; msgBase.set_eventid(eHeat); msgBase.set_msg(heat.SerializeAsString()); m_strHeatMsg = msgBase.SerializeAsString(); for (set
::iterator it = m_set_BaseView.begin() ; it!=m_set_BaseView.end() ; ++it) { BaseView* pBaseView = *it; pBaseView->loginSuceess(); } pthread_t tid; pthread_create(&tid,NULL,SocketClient::reqHeat,(void*)&m_strHeatMsg);//创建一个线程 接受客户端消息}void SocketClient::onHeat(){ CCLog("send event %d",eHeat); m_nHeatFailCount = 0;}void SocketClient::onLoginFail(){ for (set
::iterator it = m_set_BaseView.begin() ; it!=m_set_BaseView.end() ; ++it) { BaseView* pBaseView = *it; pBaseView->loginFail(); } }

SocketClient.h

#pragma once#include "SocketAdmin.h"#include "cocos2d.h"#include "google/protobuf/message_lite.h"#include "MessageEvent.h"#include "pthread.h"#include "BaseView.h"#include "table/TableBase.h"USING_NS_CC;using namespace std;#define UserID unsigned int#define BYTE   unsigned charclass BaseView;class SocketClient : public BaseSocket , public TableSocket{private:    static string m_strHeatMsg;    static set
m_set_BaseView; static int m_nHeatFailCount;//心跳失败的次数 >10 次说明掉线了private: SocketClient(); void sendMsgToServer( eEvent event ,google::protobuf::MessageLite *msg); static void *reqHeat(void *arg);public: ~SocketClient(); static SocketClient* instance(); virtual void recvMsg(string msg); void sendTableMsgToServer(eEvent event , google::protobuf::MessageLite *msg); void insertBaseView(BaseView *pBaseView); void removeBaseView(BaseView *pBaseView); void reqLogin();//登陆 void reqLeave();//离开 void reqHeat(float fTime);//心跳协议 void onLoginSucceess(string msg);//登陆反馈 用于首次登陆客户端 void onHeat(); static void onLoginFail(); };

SocketAdmin.h

#pragma once#include "cocos2d.h"#include "pthread.h"#include 
#if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)#ifndef _WINSOCKAPI_#define _WINSOCKAPI_#ifndef _WINSOCK2API_#define _WINSOCK2API_#include
#endif#endif#else#include
#include
#include
#include
typedef unsigned int SOCKET;#endifclass SocketAdmin;class BaseSocket{public: BaseSocket(); ~BaseSocket(); virtual void recvMsg(std::string msg) = 0; static void sendMsg(std::string &msg); void loginServer(std::string &msg );};class SocketAdmin {private: static BaseSocket* m_pBaseSocket; static SocketAdmin* m_pInstance; SOCKET m_clientSocket;//客户端 socket static SOCKADDR_IN m_serverAddr;//服务器地址public: SocketAdmin(); static SocketAdmin* instance(); virtual ~SocketAdmin(); void sendMsg(std::string &msg); static void* thread_recv(void* arg); static void setBaseSocket(BaseSocket *pBaseSocket) { m_pBaseSocket = pBaseSocket; } static void clearBaseSocket() { m_pBaseSocket = NULL; } void loginServer(std::string &msg);//登陆服务器};

SocketAdmin.cpp

#include "SocketAdmin.h"BaseSocket* SocketAdmin::m_pBaseSocket = NULL;SocketAdmin* SocketAdmin::m_pInstance = NULL;SOCKADDR_IN SocketAdmin::m_serverAddr;BaseSocket::BaseSocket(){    SocketAdmin::setBaseSocket(this);}BaseSocket::~BaseSocket(){    SocketAdmin::clearBaseSocket();}void BaseSocket::sendMsg( std::string &msg ){    SocketAdmin::instance()->sendMsg(msg);}void BaseSocket::loginServer(std::string &msg){    SocketAdmin::instance()->loginServer(msg);}SocketAdmin* SocketAdmin::instance(){    if(!m_pInstance) m_pInstance = new SocketAdmin();    return m_pInstance;}SocketAdmin::SocketAdmin(){    //初始化socket库#if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)    WSADATA wsaData;    if ( 0 != WSAStartup( MAKEWORD(1,1), &wsaData) )    {        return ;    }    if (LOBYTE(wsaData.wVersion) !=1 || HIBYTE(wsaData.wVersion)!=1 )    {        WSACleanup();        return ;    }#endif    m_serverAddr.sin_addr.S_un.S_addr = inet_addr("113.91.54.51");  //htonl函数是将主机字节序(小端序)转换为网络字节序(大端序)    m_serverAddr.sin_port = htons(6100);    m_serverAddr.sin_family = AF_INET;    m_clientSocket = socket(AF_INET,SOCK_DGRAM,0);}SocketAdmin::~SocketAdmin(){    WSACleanup();    closesocket(m_clientSocket);}void SocketAdmin::loginServer(std::string &msg){    sendMsg(msg);    pthread_t tid;    pthread_create(&tid,NULL,SocketAdmin::thread_recv,(void*)m_clientSocket);//创建一个线程 接受客户端消息}void* SocketAdmin::thread_recv(void* arg){    SOCKET sockfd = (SOCKET) arg;    int len = sizeof(SOCKADDR);    std::string str;    SOCKADDR_IN addr;    char buf[2000];    while (true)    {        str="";        int retval = recvfrom(sockfd , (buf) , 2000 , 0 ,(SOCKADDR*)&addr , &len);        if (SOCKET_ERROR != retval){            for (int i = 0; i < retval-1; i++)            {                str.append("0");                str[i]=buf[i];            }            m_pBaseSocket->recvMsg(str);        }else{            CCLOG("***********************************   recvMsg fail ");            break;        }    }    return NULL;;}void SocketAdmin::sendMsg(std::string &msg){    sendto(m_clientSocket , msg.c_str() , msg.length()+1 ,0 ,(SOCKADDR*)&m_serverAddr , sizeof(SOCKADDR));}

 

转载地址:https://www.cnblogs.com/codeloveme/p/4615051.html 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C语言数学库<math.h>
下一篇:SpringBoot2.X快速入门案例

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年03月19日 05时44分27秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

java operators_A guide to Java Operators 2019-04-21
java socket调试_JAVA实现SOCKET多客户端通信的案例 2019-04-21
java 使用或覆盖了已过时的api_JAVA使用或覆盖了已过时的 API 2019-04-21
java 图片旋转保存_Java 对图片90度旋转 2019-04-21
用java实现文学研究助手_数据结构文学研究助手 C语言代码实现(带源码+解析)... 2019-04-21
java gc的几种方式_GC 的三种基本实现方式 2019-04-21
wget linux java 32_通过wget在Linux上下载Java JDK会显示在许可证页面上 2019-04-21
babylonjs 设置面板位置_babylonjs 空间坐标转为屏幕坐标 2019-04-21
oracle里面如何查询sqlid,CSS_oracle中如何查看sql, --查询表状态:  select uo.O - phpStudy... 2019-04-21
oracle 查询中用case,oracle case when 在查询时候的用法。 2019-04-21
oracle正在运行的程序包,ORACLE PL/SQL编程详解之程序包的创建与应用 2019-04-21
php局部页面滚动,在访问另一页面后保留浏览器滚动位置 - php 2019-04-21
jmeter运行linux命令行,Jmeter在linux上运行(命令行运行Jmeter) 2019-04-21
linux服务器怎么添加站点,如何增加站点或虚拟主机及文件说明 2019-04-21
linux系统输入指令,Linux系统基础 - 基本操作命令 2019-04-21
linux设备管理命令,Linux命令(设备管理).doc 2019-04-21
linux 中文utf-8转gbk编码,Linux平台下 GBK编码转UTF-8编码 2019-04-21
linux安装软件在boot,在Linux系统上安装Spring boot应用的教程详解 2019-04-21
linux进入用户user1主目录,Linux系统命令提示符为[user1@localhost root]当前用户所在目录为( )... 2019-04-21
取消linux自动登录,linuxdeepin 如何取消自动登录啊? 2019-04-21