[转]cocos2d-x 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值