零毫秒通讯协议初稿
零毫秒通讯协议0.1
概述
零毫秒使用TCP通讯,端口号暂定4321
0.1版是一个经过服务器中转的、支持群聊的、不可靠的、纯文本的即时通讯软件。
0.1版没有好友系统,只是显示在线用户,所有的消息都经过服务器中转,大体上把权限都下放到客户端。
群系统只有一个主群,对所有用户可见
注意:所有字符串一律采用UTF-8编码
该版本(0.1)通讯协议不提供向后兼容,即下一个版本可能不再使用和支持该协议。
数据包头部
每个数据包都有一个20B的头部,如下:
32bit 协议版本顺序号(0.1版为1)
64bit 数据部分长度(不含头部长度)
32bit 消息类型,每一个数字代表一类消息
32bit 发送时间,时间戳
各种消息类型
大部分消息的数据部分都是字符串,因为有计划写命令行版本,字符串的话虽然降低了效率,但有助于命令行版的开发
| 消息编号 |
说明 |
发出者 |
数据部分的格式 |
对方应该返回的消息 |
消息发送条件 |
| 0 |
无法解析命令 |
S |
描述性字符串,指明最新版本的简介地址 |
无 |
无 |
| 如果服务器不支持客户端的版本号,或者解析消息失败,就发送该消息,同时断开连接 |
| 1 |
请求服务器时间 |
C |
空 |
服务器时间 |
建立连接后 |
| 2 |
要求登录 |
C |
用户名、密码、客户端版本顺序号、客户端名称描述性字符串,空格隔开。 |
登录结果 |
建立连接后 |
| 客户端版本顺序号和客户端名称描述性字符串都是用于服务器统计的,由客户端开发者自行规定。密码是经过加密的,加密方法见后面。 |
| 3 |
登录结果-成功 |
S |
空 |
无 |
客户端要求登录后 |
| 4 |
登录结果-失败 |
S |
空 |
无 |
客户端要求登录后 |
| 5 |
服务器时间 |
S |
字符串的时间戳 |
无 |
客户端请求服务器时间后 |
| 6 |
请求在线列表 |
C |
字符串的上次请求时间时间戳 |
在线列表 |
登录后 |
| 7 |
在线列表 |
S |
逗号隔开的在线用户名列表 |
无 |
客户端请求在线列表后 |
| 8 |
需要更新在线列表 |
S |
无 |
请求在线列表 |
登录后 |
| 当其他用户的在线状态有变动的时候通过本消息提醒客户端需要更新在线列表 |
| 9 |
发送消息 |
C |
发送时间、目标用户、消息内容用空格隔开 |
无 |
登录后 |
| 10 |
收到消息 |
S |
发送时间、来源用户、消息内容用空格隔开 |
无 |
登录后 |
| 发送时间是字符串格式的时间戳,用户的标识方法见后面 |
| 10 |
保持登录 |
C |
无 |
无 |
登录后 |
| 客户端每隔一段时间(暂定3分钟)发送一次该消息,表示自己还没有掉线 |
| 11 |
退出登录 |
C |
无 |
无 |
登录后 |
用户标识方法
零毫秒的用户是基于用户名的,用户名是字母、数字、中文字符的组合
在发送消息时,如果目标是用户,则直接用用户名表示,如果目标是一个群,则用星号加群名表示
0.1版只有一个主群,暂约定这个主群的名称为0,即表示为*0,再约定一个系统账户,用户名也为0
密码加密方法
加密规则(伪代码):
MD5(MD5(时间戳%10)+MD5(用户名)+MD5(密码))
时间戳、用户名、密码均为字符串,加号代表字符串拼接
客户端应当在连接后先获取服务器时间,然后计算本地时间和服务器时间的差值,然后等待下一个整10秒数进行发送,以防止数据包被发送到服务器时,密码被更新。
因为这种加密方式会受很多方面因素的影响而导致失败,所以如果验证失败,客户端应该自动进行几次重试(暂定推荐3次)
客户端的记住密码功能,和服务器数据库中的密码均为一次MD5后的密码
服务器信息的获取
客户端应该访问如下地址(暂定):
http://jybox.net/0ms.config.php
该文件是一个INI文件,提供了有关服务器的信息
[零毫秒]
serverip=173.212.235.252 ;服务器IP
clientport=4321 ;客户端连接端口
gbktelnetport=4322;GBK版telnet端口(详见后文)
utf8telnetport=4323;UTF-8版telnet端口(详见后文)
servertime=1317044870;服务器时间戳(动态的)
version=1 ;最新通讯协议顺序号
clientvirsion=1 ;最新官方客户端顺序号
versionurl=一个网址;最新版通讯协议简介地址
clienturl=一个网址;最新版官方客户端下载地址
端口和telnet
telnet是大部分重装系统都内置的一个命令行工具,用于远程Internet远程登陆服务。
零毫秒计划对telnet登录提供支持,以方便在极端情况下使用零毫秒。
而且因为上面的消息命令大多为字符串,所以要提供对telnet的支持是一件很简单的事情。
计划上,正常客户端的登录端口是4321,GBK版telnet端口是4322,UTF-8版telnet端口是4323。
为什么分编码?因为经过我的实测,windows的telnet工具的编码是GBK,而Linux的telnet工具的编码是UTF-8
至于用telnet登录到底如何输入命令,不在本文件的讨论范围之内
一个完整登录运行过程的例子
客户端启动
用户输入用户名和密码,点击登录
客户端访问http://jybox.net/0ms.config.php,获得服务器IP和端口
客户端使用TCP与服务器建立连接
服务器接受连接
客户端发送请求服务器时间命令获得服务器时间
客户端计算本地时间和服务器时间的差值,等待下一个整10秒数
客户端发送经过上述加密的密码、用户名、客户端自述信息
服务器校验密码的正确性,如果正确,向客户端发出登录结果-成功命令和需要更新在线列表命令
客户端发送请求在线列表命令
服务器返回在线列表命令
(之后将不断循环下列过程)
(用户向其他人发送消息)客户端发送发送消息命令
...
(收到其他人发来的消息)服务器发送收到消息命令
...
(有人上线或下线)服务器发送需要更新在线列表命令
客户端发送请求在线列表命令
服务器返回在线列表命令
...
(3分钟内客户端没有于服务器联系)客户端发送保持登录命令
用户选择退出
客户端发送退出登录命令
服务器断开连接
上述只是一个正常的登录过程,各种意外情况(如密码错误,无法解析命令,客户端掉线)没有提及,请各位参考上面的命令列表自行理解
|