以War3为例,启动魔兽后,首先是如何看见主机的问题:
魔兽是通过TCP/UDP协议进行数据发送的,那如何实现看到对方?我们这样:每个机器监听一个固定的UDP端口(比如6112),一旦任何机器建立主
机,它就向整个局域网所有的机器的6112端口广播“我建立了主机”的信息,这样,其他机器接收到这个信息,就知道有主机建立了(广播只存在于UDP协
议,使用UDP.sendto向地址255.255.255.255实现)。
来看看HF和VS平台怎么实现的:
1.挂钩UDP.Sendto,将所有广播信息(即发向地址255.255.255.255)的消息截获,然后把消息重新打包(比如{本机虚拟IP+消息
数据}的形式),然后使用真正的UDP.sendto把消息转到平台服务器,服务器查看有哪些玩家是跟此玩家在同一房间,把消息传给那些玩家;平台再挂钩
住接收消息用的UDP.recv
From,把UDP.recvFrom的发送方地址修改为消息中的对方虚拟IP,再把数据传给真正的UDP.recvFr om。
问:万一广播信息不是建立主机而是其他的,被误截了怎么办?
答:大部分游戏包括War3的广播信息唯一的作用就是传播“建立主机”这一类需要传给所有局域网的机器的信息,就是说只有“建立主机”这一类信息会通过地址255.255.255,因此一般不会有误截发生。
实际上通过广播的信息还有主机是否人满,地图,主机是否取消建立,等信息。
其次,如何加入游戏:
魔兽在加入游戏后使用TCP协议,每个玩家对应一个连接。
在真正的局域网中,一个玩家看到和选择一个主机后点击加入,他的机器会使用TCP请求和对方连接,(地址从UDP中获得,端口是固定的6112),如果没
有人满,被主机关闭等意外发生,主机就会答应此连接(使用TCP.accept),发送些数据(地图信息,其他玩家信息等),此玩家就加入了游戏,此后两
机器就使用这个TCP连接通讯。
回到平台,在平台中,魔兽从UDP中获得的地址是服务器的地址啊(因为UDP信息是服务器转过来的),这样发起的TCP只能链接到服务器,怎么可能连接得
上真正的玩家呢?别忘了,上面说过平台挂钩了UDP.sendTo(会把本机虚拟IP加入);挂钩了UDP.recvFrom(会把服务器这个发送方的
IP改为对方虚拟IP);
接着魔兽向对方虚拟IP发起TCP.connect,可能成功吗?当然不可能,因为实际的局域网中根本没这个IP,那怎么请求连接和接受连接呢?
平台采用了这样的办法:TCP连接是靠TCP.connect发起的,平台挂钩住这个函数,把连接向服务器的地址修改为自己(即127.0.0.1或实际
IP,一般用前者),然后再挂钩TCP.accept函数(此函数用来接受TCP连接),然后发送同样的连接请求由服务器转到另一台机器(即主机),根据
那台机器的做法决定是否答应127.0.0.1的那个TCP.connect,(注意这个TCP.accept返回的新连接是挂钩代码创建的,挂钩的代码
拥有它收到的所有数据),如果答应连接的话,是不是魔兽所有的数据就会发送到这个挂钩代码创建的连接这里了?
接着,挂钩代码把这些数据重新打包(例如{接收方机器的虚拟IP+发送数据+发送方的虚拟IP}的形式),使用UDP.sendto发到服务器,服务器从信息中获得接收方机器的虚拟IP,查找其真正的IP,并把数据发送过去,跨网的TCP发送就完成了。
(另外一台机器也按以上方法同样处理)
posted on 2010-09-01 00:30
小果子 阅读(1085)
评论(0) 编辑 收藏 引用 所属分类:
学习笔记