我想写一个网络聊天的程序,在服务器端用链表的方式存储在线玩家,每个节点存储的是与玩家通信的套接字。假如有A,B,C,D四个玩家在线,B向服务器发送信息,服务器需要把B的信息,传给A,C,D三个玩家。我想采用一下两种方法:一:把这个信息依次传给A,B,C,D四个玩家。二:在玩家链表中依次比较套接字,与B玩家的套接字不同就传送。因为在 一 中发给B是多于的,因此方法一多做了一次发送。我的问题是,这两种方法哪个效率更高?也就是多做一次发送效率更高,还是每次发送前做一次套接字比较效率更高?谢谢

解决方案 »

  1.   

    使用数组存储玩家数据,链表存储索引,比如:
    1 数组DATA[]存储玩家数据
    2 玩家数据中包含一项players(链表),存储的是其“目标玩家”在DATA[]中的索引值这样服务器在与玩家B(假如索引为2)通信时,收到消息后由DATA[2].players定位到“目标玩家链表”,挨个发送消息即可服务器与玩家使用socket通信的话肯定知道此socket通道对应的玩家,何须比较呢?
      

  2.   

    用数组存储?然后玩家把自己的索引号发到服务器?我在游戏大厅中是这么用的,但是在线玩家随时都会上线下线,用数组添加删 除,效率太低吧! 
    //为何要添加删除?这些玩家难道不需要注册用户名和密码的吗?下线了就要“删除数据”?使用套接字比较,是因为假如服务器通过套接字接收到一条信息,如果不通过比较怎么知道套接字对应的玩家呢?
    //同理,不需要发账号密码的吗?套接字只是机器互联的东西,而且套接字只对应你当前机器又不对应玩家,就算比较这个能确定玩家吗?我不太清楚你的目的是什么样的程序了,p2p的?那也不需要socket呀。。
      

  3.   

    可能我对lz的设计不是很清楚如果你是指“索引号”的更新的话,服务器没过一段时间可以根据现在的连接来更新在线玩家信息的,更新后写入玩家数据。至于玩家数组,不用删除,设置一个变量,判断此玩家现在是否处于“激活”(在线)状态即可。
    索引内容是要服务器定时刷新的,我举“索引链表”是一个例子,实际上应该有很多方法可以存放这种索引,比如hash表。套接字也可以作为“在线玩家”数据的一项,也是对应到“索引号”的吧,服务器每收到一个信息是知道其套接字的,因此不需要比较就应该知道其“索引号”(对应关系已经在连接时建立好)。常见的游戏服务器的模式中,消息都是按照lz所说的第一种方法发送的。我觉得如果是聊天程序,与其比较套接字,不如建“索引”。当然,第一种方法更简单,带宽足够的情况下直接这样不就结了
      

  4.   

    我在服务器端有一个文本文件,存储了已注册玩家的信息(只有用户名和密码)。每次服务器启动都读取这个文件然后存入一个注册
    玩家链表中,同时再建立个在线玩家链表,因为注册过的不一定在线。
    我在服务器端使用的是WSAAsyncSelect模型。当有用户登陆时,服务器端就会通过FD_ACCEPT消息检测到有连接进入。然后就根据发送过来的用户名和密码在注册玩家链表中查找,如果有相符的就是已注册的,就把该用户名添加在在线玩家链表中,同时把连接的套接字也加入(放到该用户的节点中,每个节点中都有一个字符串项和一个SOCKET项)。
    当有玩家发送过来信息后,服务器根据发送信息的套接字,在在线玩家链表中查找不同的套接字,如果不同,说明不是这个玩家发
    送的信息,那么就把信息发给这个用户。当然这是指采用第二种方法。如果用第一种,就依次发给每个玩家。所用的套接字就是存储在该用户节点中的。不知道这样写是否把我的程序结构表达清楚了。我是第一次写这种程序,所用的方法都是自己琢磨的,有不对的地方请多多指教。
      

  5.   

    那你用第一种方法就行了。服务器接发信息就够忙的了,哪有功夫去匹配套接字。对玩家来说,聊天所占带宽很小,不在乎多收这条信息;对服务器来说,广播消息很方便,你硬要一个一个发还更费时,给你个广播的帖子看看:http://www.upschool.com.cn/edu/1322/2006/413/10du275182_1.shtml