原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/1024/686.html
		Cocos2d-X网络编程
	
		Socket,俗称网络套接字,自身并不是协议,而是一个调用接口,是对TCP/IP协议的封装和应用,。常州手游开发提供了一系列办法便当开发者停止网络通讯。
	
		TCP/IP协议是运用最早的通讯协议,它是传输层协议,主要处理数据如何在网络中传输。
	
		Socket中又分为流形式与数据报形式,即TCP与UDP两种方式。
	
		TCP : Transmission Control Protocol,传输控制协议,是面向衔接的协议,也就是说,在收发数据前,必需和对方树立牢靠的衔接。一个TCP衔接必需要经过三次“对话”才干树立起来,其中的过程十分复杂,但也是最平安的。
	
		UDP : User Data Protocol,用户数据报协议。传输数据之前源端和终端不树立衔接,发送端直接把数据发送到网络,接纳端把音讯段放在队列中,应用程序每次从队列中读一个音讯段。
	
		Socket根底和通讯流程:
	
		Socket几个定义: 
	
		1)IP地址:即按照TCP/IP协议分配给本地主机的网络地址,两个进程要通讯,任一进程首先要晓得通讯对方的位置,即对方的IP。
	
		(2)端口号:用来区分本地通讯进程,一个本地的进程在通讯时均会占用一个端口号,不同的进程端口号不同,因而在通讯前必需要分配一个没有被访问的端口号。
	
		(3)衔接:指两个进程间的通讯链路。
	
		客户/效劳器形式:
	
		在TCP/IP网络应用中,通讯的两个进程间互相作用的主要形式是客户/效劳器(Client/Server, C/S)形式,即客户向效劳器发出效劳恳求,效劳器接纳到恳求后,提供相应的效劳。
	
		常州游戏开发培训Socket通讯流程:
	
		server端:
	
		1、效劳器端先初始化Socket
	
		2、当一个套接字用socket()创立后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创立的套接字号联络起来,行将名字赋予套接字,以指定本地半相关
	
		3、对端口停止监听(listen)
	
		4、调用accept阻塞,等候客户端衔接。
	
		客户端:
	
		1、客户端初始化一个Socket
	
		2、然后衔接效劳器(connect)
	
		3、假如衔接胜利,这时客户端与效劳器端的衔接就树立了。
	
		4、客户端发送数据恳求(send),效劳器端接纳恳求并处置恳求,然后把回应数据发送给客户端,客户端读取数据。
	
		5、最后关闭衔接,一次交互完毕。
	
		cocos封装的3个Socket通讯相关类:
	
		相似http,cocos2d对socket也停止了封装。提供了SocketIO,SIODelegate和SIOClient三个类。
	
		SocketIO:
	
		运用单例形式,初始化Socket,获取SIOClient。
	
		SIODelegate: 
	
		运用Socket协议,首先要继承SIODelegate,并且还要完成SIODelegate的4个虚函数
	
		// 当翻开socket衔接时会调用这个函数
	
		virtual void onConnect(cocos2d::network::SIOClient* client);
	
		// 当接纳到数据时会调用这个函数
	
		virtual void onMessage(cocos2d::network::SIOClient* client, const std::string& data);
	
		// 当socket关闭时,会调用这个函数
	
		virtual void onClose(cocos2d::network::SIOClient* client);
	
		// 当衔接错误或接纳到错误信号时会调用这个函数
	
		virtual void onError(cocos2d::network::SIOClient* client, const std::string& data);
	
		SIOClient:
	
		处置Socket的一系列动作,比方,发送数据,监听事情,断开衔接等
	
		手机App外包发送事情和事情监听:
	
		除了上面的发送Socket恳求外,Socket.io还提供了事情监听的机制,能够运用emit提交事情和数据,运用on监听事情和获取接纳到的数据。
	
		比方客户端添加如下代码
	
		client.emit("login","[{\"name\":\"myname\",\"pwd\":\"mypwd\"}]")
	
		执行该代码后会向效劳端发送login事情,并把用户名和密码传送给效劳器。
	
		效劳器端经过执行下面的代码,用来监听login事情,并获取传送过来的数据,然后在调用emit办法向客户端发送事情和数据。客户端运用on停止监听。这样就完成了客户端和效劳端之间的数据通讯。
	
		socket.on('login', function(obj){
	
		   //向一切客户端播送用户参加
	
		   io.emit('loginresult', {message:'login success'});
	
		  });
	
		代码实操:
	
		头文件:
	
		#ifndef __TestSocketIo_SCENE_H__
	
		#define __TestSocketIo_SCENE_H__
	
		#include "cocos2d.h"
	
		#include "network\SocketIO.h"
	
		USING_NS_CC;
	
		using namespace cocos2d::network;
	
		class TestSocketIo : public cocos2d::Layer
	
		,SocketIO::SIODelegate
	
		{
	
		public:
	
		    static cocos2d::Scene* createScene();
	
		    virtual bool init();
	
		CREATE_FUNC(TestSocketIo);
	
		    void menuCloseCallback(cocos2d::Ref* pSender);
	
		    //继承和完成SIODelegate四个虚函数
	
		void onConnect(SIOClient* client);
	
		void onMessage(SIOClient* client, const std::string& data);
	
		void onError(SIOClient* client, const std::string& data);
	
		void onClose(SIOClient* client);
	
		// 创立Socket
	
		SIOClient *client;
	
		};
	
		#endif // __TestSocketIo_SCENE_H__
	
		源文件:
	
		#include "TestSocketIoScene.h"
	
		Scene* TestSocketIo::createScene()
	
		{
	
		    auto scene = Scene::create();
	
		    auto layer = TestSocketIo::create();
	
		    scene->addChild(layer);
	
		    return scene;
	
		}
	
		bool TestSocketIo::init()
	
		{
	
		    if ( !Layer::init() )
	
		    {
	
		        return false;
	
		    }
	
		Size size = Director::getInstance()->getWinSize();
	
		client = nullptr;
	
		auto menu = Menu::create();
	
		menu->setPosition(Vec2::ZERO);
	
		addChild(menu);
	
		auto lblInit = Label::create("init socket","Arial",22);
	
		auto menuInit = MenuItemLabel::create(lblInit,[=](Ref *sender){
	
		// 初始化
	
		client = SocketIO::connect("ws://192.168.1.102:3000", *this);
	
		// 设置tag辨别不同恳求
	
		client->setTag("init socket");
	
		// 运用Socket.io提供的on监听事情
	
		client->on("loginresult",[=](SIOClient *client,const std::string &data){
	
		log("login result is :%s",data.c_str());
	
		});
	
		});
	
		menuInit->setPosition(size/2);
	
		menu->addChild(menuInit);
	
		auto lblSend = Label::create("send message","Arial",22);
	
		auto menuSend = MenuItemLabel::create(lblSend,[=](Ref *sender){
	
		// 发送恳求
	
		client->send("hello socket.io");
	
		});
	
		menuSend->setPosition(size.width/2,size.height/2-50);
	
		menu->addChild(menuSend);
	
		auto lblSendEvent = Label::create("emit event","Arial",22);
	
		auto menuSendEvent = MenuItemLabel::create(lblSendEvent,[=](Ref *sender){
	
		// 运用Socket.io提供的emit提交事情
	
		client->emit("login","[{\"name\":\"myname\",\"pwd\":\"mypwd\"}]");
	
		});
	
		menuSendEvent->setPosition(size.width/2,size.height/2-100);
	
		menu->addChild(menuSendEvent);
	
		    return true;
	
		}
	
		void TestSocketIo::onConnect(SIOClient* client){
	
		log("onConnect");
	
		log("%s connect",client->getTag());
	
		}
	
		void TestSocketIo::onMessage(SIOClient* client, const std::string& data){
	
		log("onMessage");
	
		log("%s received content is:%s",client->getTag(),data.c_str());
	
		}
	
		void TestSocketIo::onClose(SIOClient * client){
	
		log("onClose");
	
		log("%s is closed",client->getTag());
	
		}
	
		void TestSocketIo::onError(SIOClient* client, const std::string& data){
	
		log("onError");
	
		log("%s error is:%s",client->getTag(),data.c_str());
	
		}
	
		效劳器端:运用的node.js
	
		var io = require('socket.io').listen(3000,'192.168.1.102');
	
		console.log('Server on port 3000...');
	
		io.sockets.on('connection',function(socket)
	
		{
	
		    //向客户端发送音讯
	
		    socket.send('Hello Cocos2d-x');
	
		    //注册message事情
	
		    socket.on('message',function(data)
	
		    {
	
		        console.log(data);
	
		    });
	
		    //注册callServerEvent事情,便于客户端调用
	
		    socket.on('login',function(data0)
	
		    {
	
		        console.log(data0);
	
		        //向客户端发送音讯,触发客户端的callClientEvent事情
	
		        socket.emit('loginresult',{message:'login success'});
	
		    });
	
		});
	上篇:上一篇:android百度地图定位表现目前位置(android百度地图
下篇:下一篇:u3d怎样完成一个3D模型漂浮,上下浮动的效果


 
                     
                     
                     
                     
                    