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);
}
转帖:http://blog.csdn.net/laik228/article/details/8937022