Cocos2d-X网络编程(4) Cocos2d中的网络通信协议——Socket通信
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通信流程:
服务端:
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的一系列动作,比如,发送数据,监听事件,断开连接等
发送事件和事件监听:
除了上面的发送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'});
});
});
Cocos2d-X网络编程(4) Cocos2d中的网络通信协议——Socket通信的更多相关文章
- c++ 网络编程(二) linux 下多进程socket通信 多个客户端与单个服务端交互代码实现回声服务器
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9612820.html 锲子-- 预备知识优雅的关闭套接字连接: 基于TCP的半关闭 TCP中的 ...
- [C#网络编程系列]专题一:网络协议简介
转自:http://www.cnblogs.com/zhili/archive/2012/08/11/NetWorkProgramming.html 因为这段时间都在研究C#网络编程的一些知识, 所以 ...
- 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...
- [转帖]脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么? http://www.52im.net/thread-1732-1-1.html 1.引言 本文接上篇<脑残式网 ...
- 【TCP/IP网络编程】:01理解网络编程和套接字
1.网络编程和套接字 网络编程与C语言中的printf函数和scanf函数以及文件的输入输出类似,本质上也是一种基于I/O的编程方法.之所以这么说,是因为网络编程大多是基于套接字(socket,网络数 ...
- 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法
网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...
- Cocos2d-X网络编程(2) Cocos2d中的网络通信协议——http协议
HTTP协议也叫超文本传输协议.是互联网广泛使用的通信协议,常用于B/S架构中. HTTP连接使用的是短连接形式,也就是"请求-响应"的方式,不仅在请求时需要先建立连接,而且需要客 ...
- Cocos2d-X网络编程(3) Cocos2d中的网络通信协议——WebSocket协议
WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信.实现浏览器与服务器的即时通讯.即服务器也能主动向客户端发消息. WebSocket代理类和方法: co ...
- Linux 网络编程基础(1)--网络相关的数据结构及转化函数
在Linux下进行网络编程,使用的语言一般为C.就个人感受而言,在Linux下进行网络程序的编写,重要的不是代码能力要多强,而是对Linux的网络编程思想的理解和对Linux网络数据结构的掌握.如果想 ...
随机推荐
- java http httpclient
HttpClient post get 洗衣店 微信扫码支付
- 【视频点播最佳实践】使用OSS SDK上传视频到点播
摘要: 场景 点播上传SDK缺乏需要的语言版本(如C/C++.Go等)或相应的功能(如网络流上传.追加上传),可以直接使用OSS的SDK进行上传. 准备工作 确认已开通点播服务并完成了相关配置.确认已 ...
- 测试工具Telerik Test Studio发布R2 2019|支持VS 2019
Telerik Test Studio是一个用于功能性Web.桌面和移动测试的直观测试自动化工具,它能轻松地实现自动化测试.同时会为GUI.性能.加载和API测试提供完整的自动化测试解决方案. |更多 ...
- python 脚本制作
U盘拷贝 当U盘插入主机时 被系统识别挂载后 通过python代码自动的去读取U盘中的资料并且进行拷贝 寄存在U盘上的 把硬盘上的资料进行读取并移动到U盘里 有点像 繁殖性 传输性 破坏性 破坏系统或 ...
- 约瑟夫环(CVTE、网易2014.3.16笔试题offerP228)
题目:0,1,2,……,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 法一:用环形链表模拟圆圈的经典算法(时间复杂度O(nm),空间复杂 ...
- WinServer2008R2远程桌面长时间保持连接
开始------运行------gpedit.msc 计算机配置------管理模板-----Windows组件-----远程桌面服务------远程桌面会话主机------会话时间限制 修改两项设置 ...
- WIN 7 的vs2008 试用版评估期结束的解决方法
1. 在VS2008安装目录下把Setup/setup.sdb文件中的 [Product Key] T2CRQGDKBVW7KJR8C6CKXMW3D 改成 [Product Key] PYHYPWX ...
- css-select的三角在不同浏览器的样式是不一样的,所以我们这样解决???
select{ width:57px; height:23px; border:1px solid #e9e9e9; outline: none; appearance: none; -moz-app ...
- Shell-07数组与字符串
Shell-07数组与字符串 数组 数组说白了就是一段连续的变量,一段连续的内存存储空间 解决:变量过多的问题:在同类的变量中,我们不需要去定义多个名字,而是以数组的方式来定义:(列表) 数组名 索引 ...
- 集合比较器报错java.lang.IllegalArgumentException: Comparison method violates its general contract!
Collections.sort(listMonthlyUsage, new Comparator<MonthlyUsageDto>() { //按照元素从小到大排序 @Override ...