client使用的socket.
注意:链接时是阻塞模式,链接后转为了非阻塞.不必多线程.自己简单封装了一下提供给一些不熟悉的人看看.
linux下使用的无信号调用,IOS下忽略了SIG_IGN信号。这样做避免掉线进程被关闭.
收发消息时 LHS_EAGAIN 与 LHS_EWOULDBLOCK 错误码可以不做处理,因为本socket为非阻塞.
SOCKET_CONNECTION_ERROR 为自定义错误码.
如需转载请链接原始地址.
LHSSocket.h文件代码如下
#ifndef __LHSSOCKET_H__ #define __LHSSOCKET_H__ #include "cocos2d.h" #define SOCKET_CONNECTION_ERROR (-917) #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) #include <WinSock.h> #pragma comment (lib,"WSock32.Lib") //#include <WinSock2.h> //#pragma comment (lib,"WS2_32.Lib") #else #include <signal.h> #include <sys/socket.h> #include <netinet/in.h> #include<netinet/tcp.h> #include <netdb.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <arpa/inet.h> typedef int SOCKET; #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR (-1) #endif //error #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) #define LHS_EAGAIN WSAEWOULDBLOCK #define LHS_EWOULDBLOCK WSAEWOULDBLOCK #else #define LHS_EAGAIN EAGAIN //此操作会令线程阻塞,但socket为不可阻塞的 #define LHS_EWOULDBLOCK EWOULDBLOCK //资源暂时不可用 #endif /*************************** TCP IP ClientSocket NONBLOCK ***************************/ class LHSSocket { public: LHSSocket(); ~LHSSocket(); //初始化套接字环境 int initSocket(); //关闭套接字环境 int clearSocket(); //连接 int Connect(const char* ip, unsigned short port); //重连接 int ReConnect(const char* ip, unsigned short port); //断开连接 void disconnect(); //发送 int Send(const char* buf, int len); //获取 int Recv(char* buf, int len); //获得错误码 int getError(); protected: SOCKET m_Socket; bool m_isConnect; }; #endif //__LHSSOCKET_H__LHSSocket.cpp文件代码如下
#include "LHSSocket.h" using namespace cocos2d; static bool isSetSig=true; LHSSocket::LHSSocket(): m_Socket(INVALID_SOCKET), m_isConnect(false) { #if (CC_TARGET_PLATFORM==CC_PLATFORM_IOS) if (isSetSig) { isSetSig=false; struct sigaction Sa; Sa.sa_handler = SIG_IGN; sigaction(SIGPIPE,&Sa,0); } #endif } LHSSocket::~LHSSocket() { } int LHSSocket::initSocket() { int ret=0; #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1,1); ret=WSAStartup( wVersionRequested, &wsaData ); #endif if (m_Socket!=INVALID_SOCKET) { CCLog("Disconnect socket in <initSocket>!"); this->disconnect(); } m_Socket=socket(AF_INET,SOCK_STREAM,0); if (m_Socket==INVALID_SOCKET) { CCLog("socket socket error!"); ret=SOCKET_ERROR; } return ret; } int LHSSocket::clearSocket() { m_isConnect=false; this->disconnect(); #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) return WSACleanup(); #else return 0; #endif } int LHSSocket::getError() { #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) return (WSAGetLastError()); #else return (errno); #endif } int LHSSocket::Connect(const char* ip, unsigned short port) { int ret=SOCKET_ERROR; do { hostent* hp=gethostbyname(ip); if (!hp) { CCLog("socket gethostbyname error!"); break; } sockaddr_in svraddr; memset(&svraddr, 0, sizeof(svraddr)); memcpy((char*)&svraddr.sin_addr, hp->h_addr, hp->h_length); svraddr.sin_family = hp->h_addrtype; svraddr.sin_port = htons(port); CCLog("socket connect ip=%s,port=%d",ip,port); ret=connect(m_Socket,(sockaddr*)&svraddr,sizeof(svraddr)); if (ret!=SOCKET_ERROR) { m_isConnect=true; #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) u_long ul=1; ioctlsocket(m_Socket,FIONBIO,&ul); #else fcntl(m_Socket, F_SETFL, O_NONBLOCK); #endif } } while (0); return ret; } int LHSSocket::ReConnect(const char* ip, unsigned short port) { this->disconnect(); this->initSocket(); return this->Connect(ip,port); } void LHSSocket::disconnect() { if (m_Socket!=INVALID_SOCKET) { m_isConnect=false; #if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) closesocket(m_Socket); #else close(m_Socket); #endif m_Socket=INVALID_SOCKET; CCLog("socket disconnect"); } } int LHSSocket::Send(const char* buf, int len) { if (m_Socket==INVALID_SOCKET || !m_isConnect) { return SOCKET_CONNECTION_ERROR; } unsigned int flags=0; #if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) flags=MSG_NOSIGNAL; #endif return send(m_Socket, buf, len, flags); } int LHSSocket::Recv(char* buf, int len) { if (m_Socket==INVALID_SOCKET || !m_isConnect) { return SOCKET_CONNECTION_ERROR; } unsigned int flags=0; #if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) flags=MSG_NOSIGNAL; #endif return recv(m_Socket, buf, len, flags); }