Socket 与 WebSocket

2016-09-15 更新: 加入 PDF 版本网络协议图


去年光棍节的时候,我写过一篇 quick-cocos2d-x 中的 socket 技术选择:LuaSocket 和 WebSocket 。这篇文章介绍了我为何决定在项目中使用 LuaSocket 。

现在想起来,当时对 WebSocket 是很感兴趣的,但由于服务端的限制,最终依然选择了 LuaSocket。我后来对 LuaSocket 进行了封装,使其更好用。

现在,面对一个全新的项目,我自然而然地选择了 WebSocket。

因此,我需要了解下面这些问题:

  1. Socket 和 WebSocket 有哪些区别和联系?
  2. WebSocket 和 HTML5 是什么关系?
  3. 必须在浏览器中才能使用 WebSocket 吗?
  4. WebSocket 能和 Socket 一样传输 raw 数据么?
  5. WebSocket 和 Socket 相比会多耗费流量么?

但是,目前网上全面介绍这两种协议的中文文章并不多,或者说不够全面。我无法找到一篇文章能解决上面的所有问题。因此,我写了本文,把找到的 Socket 和 WebSocket 的相关资料做一个梳理,以方便理解。

本文并不能直接完整回答上面提出的几个问题,但读完本文,要理解上面的那些问题,是很容易的事。

由于能力有限,本文不可能很长。而且,技术细节并非所有人都愿意仔细了解。本文包含了大量的外部链接,跟随这些链接,可以找到足够多的细节,满足你/我的求知欲。


1. 概述

选择了 WebSocket 技术之后,不可避免的,我要将它和其他协议以及技术做一下比较。最常见的,就是需要比较 WebSocket 与 HTTP、Socket 技术的异同。

WebSocket 是为了满足基于 Web 的日益增长的实时通信需求而产生的。在传统的 Web 中,要实现实时通信,通用的方式是采用 HTTP 协议不断发送请求。但这种方式即浪费带宽(HTTP HEAD 是比较大的),又消耗服务器 CPU 占用(没有信息也要接受请求)。(下图来自 WebSocket.org

Latency comparison between the polling and WebSocket applications

而是用 WebSocket 技术,则会大幅降低上面提到的消耗:(下图来自 websocket.org

Comparison of the unnecessary network throughput overhead between the polling and the WebSocket applications

关于更详细的描述,尹立的这篇文章讲得非常好:WebSocket(2)–为什么引入WebSocket协议

那么,WebSocket 到底与 HTTP 协议到底是一个什么样的关系呢?它和 Socket 又有什么联系?这就要讲到 OSI 模型和 TCP/IP 协议族。 继续阅读Socket 与 WebSocket

基于quick-cocos2d-x的LuaSocket范例

这是一个 luasocket 范例

为了便于使用,我封装了 luasocket 到 cc.net.SocketTCP 类中。这个范例展示如何使用 cc.net.SocketTCP

同时,在本范例中还使用了 cc.utils.ByteArraycc.utils.ByteArrayVarint

要了解更多关于 cc.net.SocketTCPcc.utils.ByteArray 的信息,请阅读 一个LuaSocket封装用lua实现ByteArray和ByteArrayVarint .

在本范例的 net 包中,有3个 lua 类: 继续阅读基于quick-cocos2d-x的LuaSocket范例

一个LuaSocket封装

一个LuaSocket封装

2014-01-10更新: SocketTCP 已经进入 quick-cocos2d-x 的 framework.


quick-cocos2d-x 中的 socket 技术选择:LuaSocket 和 WebSocket 一文中,我提到了选择 LuaSocket 与服务器通信。

为了方便使用,我对LuaSocket进行了封装。封装主要做了这样几件事:

  1. 封装基于 LuaSocket 的 TCP 模式,使用 settimeout 实现异步调用;
  2. 利用 cocos2d-x 提供的定时器实现失败重连;
  3. 利用 quick-cocos2d-x 提供的 framework.api.EventProtocol 实现了事件的注册和发布。

这个封装完全依赖 quick-cocos2d-x ,因此不能单独在lua环境中使用。

这个封装修改自 quick 论坛的一个源码 ,感谢原作者!

下面的例子依赖 ByteArray,详情看这里:用lua实现ByteArray和ByteArrayVarint继续阅读一个LuaSocket封装

quick-cocos2d-x 中的 socket 技术选择:LuaSocket 和 WebSocket

quick-cocos2d-x 中的 socket 技术选择:LuaSocket 和 WebSocket

  • 2013-11-17更新:加入SocketTCP和ByteArray类的实现链接。
  • 2014-11-05更新:增加范例链接。
  • 2014-12-04更新:一篇更详细的文章: Socket 与 WebSocket

在 quick-cocos2d-x 中,默认集成了 LuaSocket 和 WebSocket 两个 Socket 库。那么,在开发需要长连接的手机游戏时,应该选择哪个库呢?下面从几个方面进行比较:

  1. 跨平台;
  2. 易用性;
  3. 性能;
  4. 流量;
  5. 灵活性;
  6. 二进制编码;
  7. 服务器实现。

继续阅读quick-cocos2d-x 中的 socket 技术选择:LuaSocket 和 WebSocket

在ANE中连接Socket服务器的注意事项

在ANE中连接Socket服务器的注意事项

前戏

也许你会奇怪,既然AS提供了Socket实现,为什么还要用ANE来实现Socket连接?

在ANE插件中启动AIR开发的Android应用 一文的最后,我提到了一个应用案例,我现在将这个案例明确的说明一下。

对于游戏开发者来说,我们希望能推送给用户一些消息。如果使用常规的手段,只能在用户打开游戏的时候,才能和服务器通信,收到这些消息。

如果用户几天不上线,那么可能会错过这些消息,导致游戏中的公告、奖励不能及时到达。

要解决这个问题,我们可以在Android系统中注册一个Service。这个Service长期保持与服务器的连接,或者隔段时间连接一次服务器,收到消息后马上推送给用户。

这种Service,使用AIR是无法实现的,必须用ANE来解决。因此,我们不可能使用AS的Socket来连接服务器,必须用Android SDK提供的Socket连接方法。

阻力

在JAVA中实现Socket客户端的方法很简单,这里提供一些简单(且不完整)的代码: 继续阅读在ANE中连接Socket服务器的注意事项

Socket服务器性能测试器+源码

2011-08-05升级:加入自定义数据发送的功能,规则:s字符串,b字节,i长整数,u无符号整形,n短整形。例如 :n1000,b1,i65555,s你懂的

为了测试新服务器的连接承载能力,我花了点时间写了这个测试器,但其实这只能算个雏形而已。

后来测试器使用C#重写,所以这个测试器就没再修改和更新,里面已有的BUG也没怎么解决。

目前的版本实现了以下功能:

  • 指定连接数量;
  • 允许指定连接间隔时间;
  • 发送指定大小的测试数据包;
  • 自动写入log文件(不要妄想用TextArea显示Log,最后程序会直接被log信息的更新拖死……)
  • 加入自定义数据发送的功能,规则:s字符串,b字节,i长整数,u无符号整形,n短整形。例如:n1000,b1,i65555,s你懂的

继续阅读Socket服务器性能测试器+源码

SWF帧频(FPS)对Socket连接的影响

SWF帧频(FPS)对Socket连接的影响

SWF帧频(FPS)对Socket连接的影响

Adobe官方帮助中对于Flash Player的睡眠模式有 这样一段介绍

ActionScript 代码在睡眠模式下继续执行,这与将 Stage.frameRate 属性设置为 4 fps 类似。但是跳过呈现步骤,因此用户看不到该 Player 正在以 4 fps 的速率运行。之所以将帧速率选择为 4 fps (而不是 0),是因为该速率允许所有连接保持打开状态(NetStream、Socket 和 NetConnection)。将帧速率切换到 0 fps 会断开打开的连接。之所以将刷新速率选择为 250 毫秒 (4 fps),是因为……。

确实是这样么?当FPS低于4或者为0的时候,Socket连接会断开么?低帧频的时候,通过Socket发送的数据,是根据帧率触发,还是直接触发呢?于是我写了个测试程序做了如下测试:

  • 在舞台上双击的时候,可以在帧频2和帧频0之间切换;
  • 每次EnterFrame的时候,向Socket服务器发送布尔值false;
  • 每次单击鼠标的时候,向Socket服务器发送布尔值true;
  • 在服务端,显示出每次发送数据之间的间隔,同时显示发送的数据内容(1=true,0=false)。

继续阅读SWF帧频(FPS)对Socket连接的影响

【转】Java socket – 套接字基础

转自:http://caihx.javaeye.com/blog/605143

套接字基础

1. 介绍

多数程序员,不管他们是否使用 Java语言进行编码,都不想知道很多关于不同计算机上的应用程序彼此间如何通信的低级细节。程序员们希望处理更容易理解的更高级抽象。Java程序员希望能用他们熟悉的 Java 构造,通过直观接口与对象交互。

套接字在两个领域中都存在 ―我们宁愿避开的低级细节和我们更愿处理的抽象层。本教程讨论的低级细节将只限于理解抽象应用程序所必须的部分。 继续阅读【转】Java socket – 套接字基础

【转】Http和Socket连接区别

转自:http://blog.csdn.net/zsnlovewl/archive/2009/12/12/4991820.aspx

1、TCP连接

要想明白Socket连接,先要明白TCP连接。手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。

建立起一个TCP连接需要经过“三次握手”:

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 继续阅读【转】Http和Socket连接区别