Cocos2d-x连接Mina NIO服务器要点

来源:互联网 发布:淘宝达人怎么收取佣金 编辑:程序博客网 时间:2024/05/17 01:45

1。客户端代码

odScoket.h

/*

 * define file about portable socket class. 

 * description:this sock is suit both windows and linux

 * design:odison

 * e-mail:odison@126.com>

 * 

 */


#ifndef _ODSOCKET_H_

#define _ODSOCKET_H_


#ifdef WIN32

#include <winsock.h>

typedef intsocklen_t;

#else

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <fcntl.h>

#include <unistd.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <arpa/inet.h>

typedef intSOCKET;


//#pragma region define win32 const variable in linux

#define INVALID_SOCKET -1

#define SOCKET_ERROR -1

//#pragma endregion

#endif

#include <iostream>

using namespace std;

class ODSocket {


public:

ODSocket(SOCKET sock = INVALID_SOCKET);

~ODSocket();


// Create socket object for snd/recv data

bool Create(int af,int type, int protocol = 0);


// Connect socket

bool Connect(conststring ip, unsigned short port);

//#region server

// Bind socket

bool Bind(unsignedshort port);


// Listen socket

bool Listen(int backlog =5); 


// Accept socket

bool Accept(ODSocket& s,char* fromip = NULL);

//#endregion

// Send socket

int Send(constchar* buf, int len, int flags = 0);


// Recv socket

int Recv(char* buf,int len, int flags = 0);

// Close socket

int Close();


// Get errno

int GetError();

//#pragma region just for win32

// Init winsock DLL 

static int Init();

// Clean winsock DLL

static int Clean();

//#pragma endregion


// Domain parse

static bool DnsParse(constchar* domain, char* ip);


ODSocket& operator = (SOCKET s);


operator SOCKET ();


protected:

SOCKET m_sock;


};


#endif

////////////////////////////////////////////////////////////////////////////////////

odsocket.cpp


#include "ODSocket.h"


#ifdef WIN32

#pragma comment(lib, "wsock32")

#endif



ODSocket::ODSocket(SOCKET sock)

{

m_sock = sock;

}


ODSocket::~ODSocket()

{

}


int ODSocket::Init()

{

#ifdef WIN32

/*

http://msdn.microsoft.com/zh-cn/vstudio/ms741563(en-us,VS.85).aspx


typedef struct WSAData { 

WORD wVersion; //winsock version

WORD wHighVersion; //The highest version of the Windows Sockets specification that the Ws2_32.dll can support

char szDescription[WSADESCRIPTION_LEN+1]; 

char szSystemStatus[WSASYSSTATUS_LEN+1]; 

unsigned short iMaxSockets; 

unsigned short iMaxUdpDg; 

char FAR * lpVendorInfo; 

}WSADATA, *LPWSADATA; 

*/

WSADATA wsaData;

//#define MAKEWORD(a,b) ((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8)) 

WORD version = MAKEWORD(2, 0);

int ret = WSAStartup(version, &wsaData);//win sock start up

if ( ret ) {

// cerr << "Initilize winsock error !" << endl;

return -1;

}

#endif

return 0;

}

//this is just for windows

int ODSocket::Clean()

{

#ifdef WIN32

return (WSACleanup());

#endif

return0;

}


ODSocket& ODSocket::operator = (SOCKET s)

{

m_sock = s;

return (*this);

}


ODSocket::operatorSOCKET ()

{

return m_sock;

}

//create a socket object win/lin is the same

// af:

bool ODSocket::Create(int af,int type, int protocol)

{

m_sock = socket(af, type, protocol);

if (m_sock == INVALID_SOCKET ) {

returnfalse;

}

return true;

}


bool ODSocket::Connect(conststring ip, unsigned short port)

{

struct sockaddr_in svraddr;

svraddr.sin_family = AF_INET;

svraddr.sin_addr.s_addr =inet_addr(ip.c_str());

svraddr.sin_port = htons(port);

int ret = connect(m_sock, (structsockaddr*)&svraddr, sizeof(svraddr));

if ( ret == SOCKET_ERROR ) {

returnfalse;

}

return true;

}

//for server

bool ODSocket::Bind(unsignedshort port)

{

struct sockaddr_in svraddr;

svraddr.sin_family = AF_INET;

svraddr.sin_addr.s_addr =INADDR_ANY;

svraddr.sin_port = htons(port);


int opt =  1;

if ( setsockopt(m_sock,SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(opt)) < 0

returnfalse;


int ret = bind(m_sock, (structsockaddr*)&svraddr, sizeof(svraddr));

if ( ret == SOCKET_ERROR ) {

returnfalse;

}

return true;

}


bool ODSocket::Listen(int backlog)

{

int ret = listen(m_sock, backlog);

if ( ret == SOCKET_ERROR ) {

returnfalse;

}

return true;

}


bool ODSocket::Accept(ODSocket& s,char* fromip)

{

struct sockaddr_in cliaddr;

socklen_t addrlen = sizeof(cliaddr);

SOCKET sock = accept(m_sock, (struct sockaddr*)&cliaddr, &addrlen);

if ( sock == SOCKET_ERROR ) {

returnfalse;

}


s = sock;

if ( fromip != NULL )

sprintf(fromip, "%s", inet_ntoa(cliaddr.sin_addr));


return true;

}


int ODSocket::Send(constchar* buf, int len, int flags)

{

int bytes;

int count = 0;


while ( count < len ) {


bytes = send(m_sock, buf + count, len - count, flags);

if ( bytes == -1 || bytes ==0 )

return -1;

count += bytes;


return count;

}


int ODSocket::Recv(char* buf,int len, int flags)

{

return (recv(m_sock, buf, len, flags));

}


int ODSocket::Close()

{

#ifdef WIN32

return (closesocket(m_sock));

#else

return (close(m_sock));

#endif

}


int ODSocket::GetError()

{

#ifdef WIN32

return (WSAGetLastError());

#else

return (SOCKET_ERROR);

#endif

}


bool ODSocket::DnsParse(constchar* domain, char* ip)

{

structhostent* p;

if ( (p = gethostbyname(domain)) ==NULL )

returnfalse;

sprintf(ip, 

"%u.%u.%u.%u",

(unsigned char)p->h_addr_list[0][0], 

(unsigned char)p->h_addr_list[0][1], 

(unsigned char)p->h_addr_list[0][2], 

(unsigned char)p->h_addr_list[0][3]);

return true;

}

///////////////////////////////////////////////////////

//鉴证奇迹的时刻

 cSocket.Init();

 cSocket.Create(AF_INET,SOCK_STREAM,0);

    char ipaddr[20];

    cSocket.DnsParse("aliyun-027.btcsky.com", ipaddr);

bool res=cSocket.Connect(ipaddr,1234);

      CCLog("socket connection %d", res);

char recvBuf[1024];

char recvBuf1[1024];

    char *s1,*s2, *s3, *s4;

    char *out_buf1, *out_buf2;

    size_t out_len = 4096;

    ssize_t rc;

    char *s ="零一二三四五六七八九十0123456789abcdefghijklmnopqrstuvwxyz\r\n";///////////////////////////////注意最后加\r\n ,这个我解决了一周

    

    out_buf1 = (char *)malloc(out_len+1);

    memset(out_buf1,0, out_len+1);

    rc = convert("gb2312","utf-8", s, strlen(s), out_buf1, out_len);

    int dat=9988;

    cSocket.Send(out_buf1,strlen(out_buf1),0);

int a = 0;

a = cSocket.Recv(recvBuf,1024,0);

string ss2(recvBuf1);

cout<<ss2<<endl;

while(true){

int a = 0;

a = cSocket.Recv(recvBuf,1024,0);

CCLog("%d", a);

string s(recvBuf);

cout<<s<<endl;

cin.get();

CCLog("%s",s.c_str());

}

////////////////////////////////////////////////////////////////////////////////////////////

////服务器代码

package org.apache.mina.example.chat;


import java.net.InetSocketAddress;
import java.nio.charset.Charset;


import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;


/**
 * (<b>Entry point</b>) Chat server
 * 
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class Main {
/** Choose your favorite port number. */
private static final int PORT = 1234;


/** Set this to true if you want to make the server SSL */
private static final boolean USE_SSL = false;
private final static Charset charset = Charset.forName("gb2312");


public static void main(String[] args) throws Exception {
NioSocketAcceptor acceptor = new NioSocketAcceptor();
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();


MdcInjectionFilter mdcInjectionFilter = new MdcInjectionFilter();
chain.addLast("mdc", mdcInjectionFilter);


// Add SSL filter if SSL is enabled.
if (USE_SSL) {
addSSLSupport(chain);
}


chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
      // chain.addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
addLogger(chain);


// Bind
ChatProtocolHandler ch=new ChatProtocolHandler();
ChatProtocolHandler.isrun=true;
acceptor.setHandler(ch);
acceptor.bind(new InetSocketAddress(PORT));


System.out.println("Listening on port " + PORT);
//启动线程job
Thread t=new Thread(ch);
t.start();

}


private static void addSSLSupport(DefaultIoFilterChainBuilder chain) throws Exception {
SslFilter sslFilter = new SslFilter(BogusSslContextFactory.getInstance(true));
chain.addLast("sslFilter", sslFilter);
System.out.println("SSL ON");
}


private static void addLogger(DefaultIoFilterChainBuilder chain) throws Exception {
chain.addLast("logger", new LoggingFilter());
System.out.println("Logging ON");
}

}

/////////////至于如何编写处理器ChatProtocolHandler请详见 mina示例

/////////////////另外iconv实现了代码的转码,这个也解决了很久,终于搞定在Android ios windows上正常运行