登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
登录
注册
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
1
Star
0
简锋
/
服务器编程
代码
Issues
17
Pull Requests
0
Wiki
流水线
服务
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
封装Client类
待办的
#I43CKB
简锋
拥有者
创建于
2021-08-01 13:03
"MessageHeader.hpp" enum CMD { CMD_LOGIN, CMD_LOGIN_RESULT, CMD_LOGOUT, CMD_LOGOUT_RESULT, CMD_NEW_USER_JOIN, CMD_ERROR }; struct DataHeader { short dataLength; short cmd; }; //DataPackage struct Login : public DataHeader { Login() { dataLength = sizeof(Login); cmd = CMD_LOGIN; } char userName[32]; char PassWord[32]; }; struct LoginResult : public DataHeader { LoginResult() { dataLength = sizeof(LoginResult); cmd = CMD_LOGIN_RESULT; result = 0; } int result; }; struct Logout : public DataHeader { Logout() { dataLength = sizeof(Logout); cmd = CMD_LOGOUT; } char userName[32]; }; struct LogoutResult : public DataHeader { LogoutResult() { dataLength = sizeof(LogoutResult); cmd = CMD_LOGOUT_RESULT; result = 0; } int result; }; struct NewUserJoin : public DataHeader { NewUserJoin() { dataLength = sizeof(NewUserJoin); cmd = CMD_NEW_USER_JOIN; scok = 0; } int scok; }; "EasyTcpClient.hpp" #ifndef _EasyTcpClient_hpp_ #define _EasyTcpClient_hpp_ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include<windows.h> #include<WinSock2.h> #pragma comment(lib,"ws2_32.lib") #else #include<unistd.h> //uni std #include<arpa/inet.h> #include<string.h> #define SOCKET int #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR (-1) #endif #include <stdio.h> #include "MessageHeader.hpp" class EasyTcpClient { SOCKET _sock; public: EasyTcpClient() { _sock = INVALID_SOCKET; } virtual ~EasyTcpClient() { Close(); } //初始化socket void InitSocket() { #ifdef _WIN32 //启动Windows socket 2.x环境 WORD ver = MAKEWORD(2, 2); WSADATA dat; WSAStartup(ver, &dat); #endif if (INVALID_SOCKET != _sock) { printf("<socket=%d>关闭旧连接...\n", _sock); Close(); } _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == _sock) { printf("错误,建立Socket失败...\n"); } else { printf("建立Socket成功...\n"); } } //连接服务器 int Connect(char* ip,unsigned short port) { if (INVALID_SOCKET == _sock) { InitSocket(); } // 2 连接服务器 connect sockaddr_in _sin = {}; _sin.sin_family = AF_INET; _sin.sin_port = htons(port); #ifdef _WIN32 _sin.sin_addr.S_un.S_addr = inet_addr(ip); #else _sin.sin_addr.s_addr = inet_addr(ip); #endif int ret = connect(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in)); if (SOCKET_ERROR == ret) { printf("错误,连接服务器失败...\n"); } else { printf("连接服务器成功...\n"); } return ret; } //关闭套节字closesocket void Close() { if (_sock != INVALID_SOCKET) { #ifdef _WIN32 closesocket(_sock); //清除Windows socket环境 WSACleanup(); #else close(_sock); #endif _sock = INVALID_SOCKET; } } //处理网络消息 bool OnRun() { if (isRun()) { fd_set fdReads; FD_ZERO(&fdReads); FD_SET(_sock, &fdReads); timeval t = { 1,0 }; int ret = select(_sock + 1, &fdReads, 0, 0, &t); if (ret < 0) { printf("<socket=%d>select任务结束1\n", _sock); return false; } if (FD_ISSET(_sock, &fdReads)) { FD_CLR(_sock, &fdReads); if (-1 == RecvData(_sock)) { printf("<socket=%d>select任务结束2\n", _sock); return false; } } return true; } return false; } //是否工作中 bool isRun() { return _sock != INVALID_SOCKET; } //接收数据 处理粘包 拆分包 int RecvData(SOCKET _cSock) { //缓冲区 char szRecv[4096] = {}; // 5 接收客户端数据 int nLen = (int)recv(_cSock, szRecv, sizeof(DataHeader), 0); DataHeader* header = (DataHeader*)szRecv; if (nLen <= 0) { printf("与服务器断开连接,任务结束。\n"); return -1; } recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0); OnNetMsg(header); return 0; } //响应网络消息 void OnNetMsg(DataHeader* header) { switch (header->cmd) { case CMD_LOGIN_RESULT: { LoginResult* login = (LoginResult*)header; printf("收到服务端消息:CMD_LOGIN_RESULT,数据长度:%d\n", login->dataLength); } break; case CMD_LOGOUT_RESULT: { LogoutResult* logout = (LogoutResult*)header; printf("收到服务端消息:CMD_LOGOUT_RESULT,数据长度:%d\n", logout->dataLength); } break; case CMD_NEW_USER_JOIN: { NewUserJoin* userJoin = (NewUserJoin*)header; printf("收到服务端消息:CMD_NEW_USER_JOIN,数据长度:%d\n", userJoin->dataLength); } break; } } //发送数据 int SendData(DataHeader* header) { if (isRun() && header) { return send(_sock, (const char*)header, header->dataLength, 0); } return SOCKET_ERROR; } private: }; #endif "Client.cpp" #include "EasyTcpClient.hpp" #include<thread> void cmdThread(EasyTcpClient* client) { while (true) { char cmdBuf[256] = {}; scanf("%s", cmdBuf); if (0 == strcmp(cmdBuf, "exit")) { client->Close(); printf("退出cmdThread线程\n"); break; } else if (0 == strcmp(cmdBuf, "login")) { Login login; strcpy(login.userName, "lyd"); strcpy(login.PassWord, "lydmm"); client->SendData(&login); } else if (0 == strcmp(cmdBuf, "logout")) { Logout logout; strcpy(logout.userName, "lyd"); client->SendData(&logout); } else { printf("不支持的命令。\n"); } } } int main() { EasyTcpClient client; client.Connect("127.0.0.1", 4567); //启动UI线程 std::thread t1(cmdThread, &client); t1.detach(); while (client.isRun()) { client.OnRun(); //printf("空闲时间处理其它业务..\n"); //Sleep(1000); } client.Close(); printf("已退出。\n"); getchar(); return 0; }
"MessageHeader.hpp" enum CMD { CMD_LOGIN, CMD_LOGIN_RESULT, CMD_LOGOUT, CMD_LOGOUT_RESULT, CMD_NEW_USER_JOIN, CMD_ERROR }; struct DataHeader { short dataLength; short cmd; }; //DataPackage struct Login : public DataHeader { Login() { dataLength = sizeof(Login); cmd = CMD_LOGIN; } char userName[32]; char PassWord[32]; }; struct LoginResult : public DataHeader { LoginResult() { dataLength = sizeof(LoginResult); cmd = CMD_LOGIN_RESULT; result = 0; } int result; }; struct Logout : public DataHeader { Logout() { dataLength = sizeof(Logout); cmd = CMD_LOGOUT; } char userName[32]; }; struct LogoutResult : public DataHeader { LogoutResult() { dataLength = sizeof(LogoutResult); cmd = CMD_LOGOUT_RESULT; result = 0; } int result; }; struct NewUserJoin : public DataHeader { NewUserJoin() { dataLength = sizeof(NewUserJoin); cmd = CMD_NEW_USER_JOIN; scok = 0; } int scok; }; "EasyTcpClient.hpp" #ifndef _EasyTcpClient_hpp_ #define _EasyTcpClient_hpp_ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include<windows.h> #include<WinSock2.h> #pragma comment(lib,"ws2_32.lib") #else #include<unistd.h> //uni std #include<arpa/inet.h> #include<string.h> #define SOCKET int #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR (-1) #endif #include <stdio.h> #include "MessageHeader.hpp" class EasyTcpClient { SOCKET _sock; public: EasyTcpClient() { _sock = INVALID_SOCKET; } virtual ~EasyTcpClient() { Close(); } //初始化socket void InitSocket() { #ifdef _WIN32 //启动Windows socket 2.x环境 WORD ver = MAKEWORD(2, 2); WSADATA dat; WSAStartup(ver, &dat); #endif if (INVALID_SOCKET != _sock) { printf("<socket=%d>关闭旧连接...\n", _sock); Close(); } _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == _sock) { printf("错误,建立Socket失败...\n"); } else { printf("建立Socket成功...\n"); } } //连接服务器 int Connect(char* ip,unsigned short port) { if (INVALID_SOCKET == _sock) { InitSocket(); } // 2 连接服务器 connect sockaddr_in _sin = {}; _sin.sin_family = AF_INET; _sin.sin_port = htons(port); #ifdef _WIN32 _sin.sin_addr.S_un.S_addr = inet_addr(ip); #else _sin.sin_addr.s_addr = inet_addr(ip); #endif int ret = connect(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in)); if (SOCKET_ERROR == ret) { printf("错误,连接服务器失败...\n"); } else { printf("连接服务器成功...\n"); } return ret; } //关闭套节字closesocket void Close() { if (_sock != INVALID_SOCKET) { #ifdef _WIN32 closesocket(_sock); //清除Windows socket环境 WSACleanup(); #else close(_sock); #endif _sock = INVALID_SOCKET; } } //处理网络消息 bool OnRun() { if (isRun()) { fd_set fdReads; FD_ZERO(&fdReads); FD_SET(_sock, &fdReads); timeval t = { 1,0 }; int ret = select(_sock + 1, &fdReads, 0, 0, &t); if (ret < 0) { printf("<socket=%d>select任务结束1\n", _sock); return false; } if (FD_ISSET(_sock, &fdReads)) { FD_CLR(_sock, &fdReads); if (-1 == RecvData(_sock)) { printf("<socket=%d>select任务结束2\n", _sock); return false; } } return true; } return false; } //是否工作中 bool isRun() { return _sock != INVALID_SOCKET; } //接收数据 处理粘包 拆分包 int RecvData(SOCKET _cSock) { //缓冲区 char szRecv[4096] = {}; // 5 接收客户端数据 int nLen = (int)recv(_cSock, szRecv, sizeof(DataHeader), 0); DataHeader* header = (DataHeader*)szRecv; if (nLen <= 0) { printf("与服务器断开连接,任务结束。\n"); return -1; } recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0); OnNetMsg(header); return 0; } //响应网络消息 void OnNetMsg(DataHeader* header) { switch (header->cmd) { case CMD_LOGIN_RESULT: { LoginResult* login = (LoginResult*)header; printf("收到服务端消息:CMD_LOGIN_RESULT,数据长度:%d\n", login->dataLength); } break; case CMD_LOGOUT_RESULT: { LogoutResult* logout = (LogoutResult*)header; printf("收到服务端消息:CMD_LOGOUT_RESULT,数据长度:%d\n", logout->dataLength); } break; case CMD_NEW_USER_JOIN: { NewUserJoin* userJoin = (NewUserJoin*)header; printf("收到服务端消息:CMD_NEW_USER_JOIN,数据长度:%d\n", userJoin->dataLength); } break; } } //发送数据 int SendData(DataHeader* header) { if (isRun() && header) { return send(_sock, (const char*)header, header->dataLength, 0); } return SOCKET_ERROR; } private: }; #endif "Client.cpp" #include "EasyTcpClient.hpp" #include<thread> void cmdThread(EasyTcpClient* client) { while (true) { char cmdBuf[256] = {}; scanf("%s", cmdBuf); if (0 == strcmp(cmdBuf, "exit")) { client->Close(); printf("退出cmdThread线程\n"); break; } else if (0 == strcmp(cmdBuf, "login")) { Login login; strcpy(login.userName, "lyd"); strcpy(login.PassWord, "lydmm"); client->SendData(&login); } else if (0 == strcmp(cmdBuf, "logout")) { Logout logout; strcpy(logout.userName, "lyd"); client->SendData(&logout); } else { printf("不支持的命令。\n"); } } } int main() { EasyTcpClient client; client.Connect("127.0.0.1", 4567); //启动UI线程 std::thread t1(cmdThread, &client); t1.detach(); while (client.isRun()) { client.OnRun(); //printf("空闲时间处理其它业务..\n"); //Sleep(1000); } client.Close(); printf("已退出。\n"); getchar(); return 0; }
评论 (
0
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已关闭
负责人
未设置
标签
未设置
标签管理
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(1)
1
https://gitee.com/linux_jianfeng123/server-programming.git
git@gitee.com:linux_jianfeng123/server-programming.git
linux_jianfeng123
server-programming
服务器编程
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册