#ifdef EasyTcpClient.hpp #define EasyTcpClient.hpp #endif #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <WinSock2.h> #include <windows.h> #pragma comment(lib,"ws2_32.lib") #else #include <unistd.h> #include <arpa/inet.h> #include <string.h> #include <stdint.h>
#define SOCKET int #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR (-1) #endif #include "MessageHeader.hpp" #include <iostream> #include <thread> using namespace std;
class EasyTcpClient { SOCKET _sock; public: EasyTcpClient() { _sock = INVALID_SOCKET; } virtual ~EasyTcpClient() {
}
void InitSocket() { #ifdef _WIN32 WORD ver = MAKEWORD(2, 2); WSADATA dat; WSAStartup(ver, &dat); #endif if (IsRun()) { cout << "<socket = " << (int)_sock << "> 关闭旧连接..." << endl; Close(); } _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (!IsRun()) { cout << "<socket = " << (int)_sock << ">建立Socket失败..." << endl; } else { cout << "<socket = " << (int)_sock << ">建立Socket成功..." << endl; }
}
int Connect(const char* ip, unsigned short port) { if (!IsRun()) { InitSocket(); } 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 cout << "<socket = " << (int)_sock << "> 正在连接服务器<port:" << port << ">..." << endl; int ret = connect(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in)); if (SOCKET_ERROR == ret) { cout << "<socket = " << (int)_sock << "> 连接服务器<port:" << port << ">失败..." << endl; } else { cout << "<socket = " << (int)_sock << "> 连接服务器<port:" << port << ">成功..." << endl; } return ret; }
void Close() { if (IsRun()) { #ifdef _WIN32 closesocket(_sock); WSACleanup(); #else close(_sock); #endif _sock = INVALID_SOCKET; }
} void OnNetMsg(DataHeader* header) { switch (header->cmd) { case CMD_LOGIN_RESULT: {
LoginResult* login = (LoginResult*)header; cout << "<socket = " << (int)_sock << ">收到服务端消息:CMD_LOGIN_RESULT, 数据长度:" << login->dataLength << endl; break; } case CMD_LOGOUT_RESULT: { LogoutResult* logout = (LogoutResult*)header; cout << "<socket = " << (int)_sock << ">收到服务端消息:CMD_LOGOUT_RESULT, 数据长度:" << logout->dataLength << endl; break; } case CMD_NEW_USER_JOIN: { NewUserJoin* userJoin = (NewUserJoin*)header; cout << "<socket = " << (int)_sock << ">收到服务端消息:CMD_LOGOUT_RESULT, 数据长度:" << userJoin->dataLength << endl; break; } } }
int RecvData(SOCKET _cSock) { char szRecv[4096] = {}; int nLen = recv(_cSock, szRecv, sizeof(DataHeader), 0); DataHeader* header = (DataHeader*)szRecv; if (nLen <= 0) { cout << "<socket = " << (int)_sock << ">与服务器断开连接,任务结束..." << endl; return -1; } recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0); OnNetMsg(header); return 0; }
bool OnRun() { if (IsRun()) { fd_set fdReads; FD_ZERO(&fdReads); FD_SET(_sock, &fdReads); timeval t = { 0,0 }; int ret = select(_sock + 1, &fdReads, 0, 0, &t); if (ret < 0) { cout << "<socket = " << (int)_sock << ">select任务结束1..." << endl; Close(); return false; }
if (FD_ISSET(_sock, &fdReads)) { FD_CLR(_sock, &fdReads); if (-1 == RecvData(_sock)) { cout << "<socket = " << (int)_sock << ">select任务结束2..." << endl; Close(); return false; } } } return true; } bool IsRun() {
return _sock != INVALID_SOCKET; } int SendData(DataHeader* header) { if(IsRun() && header) return send(_sock, (const char*)header, header->dataLength, 0); return SOCKET_ERROR; }
private:
};
|