我还在考虑这个聊天室的问题,服务器与客户端之间使用tcp连接,客户端与客户端之间直接使用udp传输信息,这里有一些问题我不清楚,请大家帮帮忙。1.服务器端应该用阻塞还是非阻塞的?哪种更好?如果使用多线程,为每个连接建立一个线程可取吗?我怕cpu被废掉!2.udp的包如何解决丢包出错的问题?看到好多人说打包,是指定义传输时的数据结构吗?还有就是怎样在包上打上序号?
请高手多多指点,急切!

解决方案 »

  1.   

    1、如果客户端在200个以内用TCP还可以接受,如一楼所说,启动主监听进程,每个客户端连接进来就再开一线程用同步SOCKET进行处理。但是仅仅适用于较少的客户端。再多的客户端就必须使用UDP了。2、至于通讯时UDP丢包的问题可以这样处理:
    首先定义一个包头,里面包含你说的序号(在一定时间内不重复),方向(是发出的还是收到的),长度等等,然后每发出一个UDP包都将该包压入队列,而对方收到该包时必须回包,回包采用相同的序号,方向标记置为"回复",发送方收到该回包以后从队列中找出相同序号而方向是"发出"的包并从队列中删除,从而证明一次完整的UDP通讯交互完成。而发送方检测到一个包在发出一定时间后该包仍在队列中,可以判定该次通讯未正常完成,就根据需要决定是否重发。一个典型的UDP包头:
    typedef struct
    {
        DWORD   dwSerialID;  //包序列号
        BYTE    byteDire;    //方向
        BYTE    byteFunc;    //功能号
        DWORD   dwLen;       //包长度
    }另外还可以定义一些时间标识,校验标识等等
      

  2.   

    1. 建议使用非阻塞异步socket,性能、扩展性好
    2. 包结构可以根据需要自定义,接受方按照定义好的格式解包
      

  3.   

    多谢involute(哼哼唧唧) ,等着拿分啊,不过还有个问题,既然是包头,那就是说我在传输的时候,要把包头和数据一起发,如果只是确认,数据那部分怎么办呀?有点笨,见笑!
      

  4.   

    还有就是关于包大小的问题,我看到如果传输过程中,某一部分的MTU比我的包小,那么包会被分片。那么包应该多大才最合适,还有如果被分片,会不会产生更多的错误呢?
      

  5.   

    完整的UDP包=包头+数据
    回复包数据可以只有1字节表示状态嘛,或者干脆不需要数据,或者利用回复包完成某些功能,当然回复不能进行需要等待的操作,否则对方可能就判断发送超时了。UDP本身就是不可靠的通讯,当然对方收到也完全可能是面目全非的数据包,切片传送传丢了某些片也是有可能的,所以才要加包的数据长度和完整性校验。一个聊天室用的UDP包,限制大小在1K应该能满足需要了吧,大不了就多分几个呗。