您的位置:首页 > 理论基础 > 计算机网络

"虚拟校园"网络组件开发笔记

2011-09-05 13:57 316 查看
最近帮助本科“虚拟校园”项目小组做了网络组件的开发,历时三天,在回顾旧知识的同时遇到了一些新的问题。

最开始考虑调用第三方API实现网络功能,在网上找到了两个网络组件库POCO、RakNet,这两个库都是做网络游戏开发时常用的且都开放源码,前者完全免费,后者则有两种版权,如果做免费游戏则RakNet免费,若有商业行为需要付费。二者的差别没有具体考量,优劣也就无从比较。与HE师兄沟通之后,他推荐我使用中间件技术,并给我描述了“服务器发布、客户端注册”基本机制,根据经验他推断POCO应该也有类似的机制。于是打算使用POCO,在网上查找了一系列POCO资料(主要是官网提供的源码和API文档),源码包中的例子都是偏向具体应用的,比如文件下载等,与自己的设计目标差距较大。之前没有使用过类似的网络库,感觉有点无从下手,而项目小组的时间也比较紧了。无奈之余,抛开第三方库,从设计目标对网络组件进行了重新构思:

客户注册、运动信息传输、聊天内容传输,服务器端主要进行数据包转发,客户端则负责对消息进行解析,即“瘦服务器,胖客户端”。



网络组件连接图
这个目标不难,使用最基本的SOCKET编程也可以实现,并且也不会太复杂。时间有限,容不得太多考虑,直接着手设计。

手头已有的基于TCP通信框架是这样:服务器端侦听客户连接,为每个新连接创建一个线程与客户通信;客户端主线程进行连接初始化之后循环等待,消息接收线程负责通信。这里面只涉及最基本的字符串转发的处理。

需要完成的工作有:

A.客户端注册。每个客户端有唯一的身份标识和唯一的姓名。在连接到服务器之后,需要进行一个注册的过程,即服务器为客户端分配标识符,同时与客户端协商命名。

B.消息分类。至少需要四种不同的消息:

B.1 用户信息,用于通知在线客户状态。

B.2 运动信息,用于同步在线人物活动状态。

B.3 私聊信息,玩家指定聊天对象发送消息。

B.4 群聊消息。即玩家向所有在线客户发送的消息。

C.服务器端分类转发。服务器主要根据消息类型做转发操作,主要有广播和定点传输之分。

D.客户端消息解析。客户端根据消息类型进行不同处理。比如:接收到用户信息,则添加或调整当前在线人数列表。接收到运动消息,则将对应的客户定位到对应坐标,并调整其运动状态。私聊和群聊信息则直接显示在本地对话框中用于提示用户。

消息类型

消息内容

消息说明

ECHOMSG

用户信息(56Bytes)

用户注册,命名协商

USERMSG

用户信息(56Bytes)

通知在线客户

MOVEMSG

运动信息(60Bytes)

同步运动状态

MCHATMSG

聊天信息(1028Bytes)

群聊信息

SCHATMSG

聊天信息(1032Bytes)

私聊信息

消息格式
已解决的问题:

1. 消息格式定义。解决办法:在缓存第一个字节设置消息类型,从第二个字节开始传输具体消息内容。客户端在接收消息的时候首先根据数据(通常是字符串数组)第一个字节判断消息类型,再根据消息类型作不同处理。

2. 客户端在线客户不稳定。在新客户接入服务器的时候,服务器会将当前所有在线客户信息列表发送给它,但这个是不稳定的(很奇怪,TCP不是面向连接的通信么?),客户端收到的信息总会出现遗漏的情况。解决的办法是:服务器端主线程不断广播(程序中设置的是一秒钟广播一次)当前在线客户信息列表,客户端通过不断对比来确定其它在线客户。

3. 多线程字符串交叉显示。多线程程序中如果两个线程同时有输出操作,那么常常会出现这样的情况。线程1输出字符是ABC;线程2输出字符是abc;屏幕显示的结果很可能会是:ABaCbc。不完全解决方案是,在字符串输出前让线程睡眠一段时间Sleep(10),这样错开显示的时间,但并没从根本上解决问题。

不太明确的问题:

1. 在网络不稳定的情况下,如何保证客户端连接到服务器,并维持较为稳定的通信?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐