最近想做一个C/S的通用服务器,在开发过程中,遇到一些问题,请大家给出出招,要分我可以另开贴给问题1、在常见的C/S体系中,用户端始终是用一个socket与服务器通讯还是每个信息传输过程都新建一个socket?问题2、我知道在一些C/S系统中,采用“心跳”来通知服务器用户在线,问题是:假设用户A整操作时掉电了,在服务器中会有一个A用户的socket处于“僵尸”状态,如果该用户在小于系统约定的“僵尸”检查周期内(假设服务器没30秒检查一次僵尸,用户在掉电20秒后又上线)重新上线,这时服务器中同时有2个该用户socket,一个socket正常返回心跳包,另一个一直无反应,服务器如何将这2个内容(IP地址、用户名、密码)完全一致的socket分开,只关闭错误的socket,正确的保持继续通讯;如果要限制每个用户只能有一个socket与服务器通讯,那么对于一个漫长的通讯,用户要长时间等待(比如传输10G文件到服务器并写入数据库操作),这显然不太合理问题3、如何回退数据库操作?假设有一个耗时操作,用户发送10G文件到服务器,并写入数据库,操作流程如下表示(字母代表该过程)
用户端:打开文件(A)-----发送数据(B)---------等待服务器的处理结果(C)
服务器端:接收文件数据(D)---------文件接收结束(E)--------------写入数据库(F)--------得到数据库处理结果(G)------发送处理结果(H)
如果用户端在C状态执行“取消”操作(太耗时,反悔了),此时服务器正执行F操作,这时该如何响应用户的撤销请求?此时,并不知道服务器的执行结果,也不知道数据写到何处,甚至可能该操作的表都没有关键字(就是个流水记录表)问题4、如何终止指定的线程正常C/S体系中,服务器是开新线程来和用户完成数据交换的,如果某个数据交换过程中用户端掉电,服务器中就会有一个僵尸线程,如何关闭这个僵尸线程?目前能想到的最好结果是:使用一个标识,线程在操作时 时时读取该标识的值,发现是终止操作,处理已经得到的数据,之后正常终止,但是,要是线程也僵尸了,就无法读取标识的值了,如何安全强制关闭指定的线程?

解决方案 »

  1.   

    socket是要关闭通讯的时候才关的吧,不是每个信息就建。学习ing
      

  2.   

    第一、用户用几个socket,这取决于你采用的协议、UDP or TCP,以及客户端的操作,一般一个就够了
          如果同时传输文件什么可以再开socket。第二、你的服务器端必须有超时检查,心跳包或者连续操作的时候。第三、对于磁盘和数据库操作,你必须保证可以回滚的。第四、如果通过开新线程和用户端通讯的话,你服务器端和客户端的线程必须拥有自我检查、保护、关闭的功 
          能,线程应该可以检查对方是否还在线,是否还有响应。不需要通过什么标志。
          线程是否还要继续工作,取决于服务器端或客户端的工作状态、以及是否已经完成。状态坏了,服务器
          端或客户端必须自动退出并完成相应的处理,工作完成后,双方都可以通知对方退出。
          另外如果通过新开线程的方式处理,那么2000个线程就是上限了。
          微软提供了IOCP模式,应对大规模socket处理,。Net已经封装了该功能,
          采用socket的异步方式就是启用IOCP。一般几千个socket不在话下
      

  3.   

    连接方式存在长连接(可以理解为至始至终为一个socket)与短连接(每次使用的socket不同)两种方式,选择哪种方式取决与你的功能处理和你选择的协议。比如说一个客户端做出的操作需要服务器通知其它的客户端或是说服务器需要时刻知道客户端的状态,那么这时候需要客户端为长连接,而客户端得即时收发操作可以为短连接。
      

  4.   

    第一、用户用几个socket,这取决于你采用的协议、UDP or TCP,以及客户端的操作,一般一个就够了
      如果同时传输文件什么可以再开socket。第二、你的服务器端必须有超时检查,心跳包或者连续操作的时候。第三、对于磁盘和数据库操作,你必须保证可以回滚的。第四、如果通过开新线程和用户端通讯的话,你服务器端和客户端的线程必须拥有自我检查、保护、关闭的功  
      能,线程应该可以检查对方是否还在线,是否还有响应。不需要通过什么标志。
      线程是否还要继续工作,取决于服务器端或客户端的工作状态、以及是否已经完成。状态坏了,服务器
      端或客户端必须自动退出并完成相应的处理,工作完成后,双方都可以通知对方退出。
      另外如果通过新开线程的方式处理,那么2000个线程就是上限了。
      微软提供了IOCP模式,应对大规模socket处理,。Net已经封装了该功能,
      采用socket的异步方式就是启用IOCP。一般几千个socket不在话下 
     
    -------------------------------------------------------------------
    数据库操作可以回滚,磁盘也能回滚?交涉用户决定删除某个文件,也能回滚?第二、你的服务器端必须有超时检查,心跳包或者连续操作的时候。第四、如果通过开新线程和用户端通讯的话,你服务器端和客户端的线程必须拥有自我检查、保护、关闭的功  
      能,线程应该可以检查对方是否还在线,是否还有响应。不需要通过什么标志。
      线程是否还要继续工作,取决于服务器端或客户端的工作状态、以及是否已经完成。状态坏了,服务器
      端或客户端必须自动退出并完成相应的处理,工作完成后,双方都可以通知对方退出。第二、第四条 要是彼此通讯的时候,应该这样要求,一个业务处理完了,用户端是否还要在服务器上保持一个活连接,要是上线用户都不干活(都在线),这样的情况,会影响准备干活的用户连接,要是不用保持一个活连接,有事随时连上来,这种要求就没必要,在实际中,是保持活连接的多还是有事连一次,没事退出的多?如果不用标识,服务器如何关闭指定的僵尸线程?能不能说说具体做法?“状态坏了,服务器
      端或客户端必须自动退出并完成相应的处理,工作完成后,双方都可以通知对方退出。”说是这么说,既然状态都坏了,一端通知对方退出,对方如何能保证一定退出?
      

  5.   

    你问的真多啊。
    采用线程方式的时候,服务器端必须有一个线程管理对象,自己编,用来管理所有的连接线程。另外 你记住:让你的僵尸知道自己是僵尸我写的的线程,如果客户端停电、异常关机等等条件下都可以自动关闭的。让线程自己去处理这些,否则,你还得再开线程去监视这些操作即使客户端异常掉线,马上有连线的情况下,虽然ip什么都一样,但是socket对象永远不会和上一个一样的。
      

  6.   

    to isjoe
    ---------------能否说一下,你做的这个是自己设计的框架还是用的IOCP,我是自己写的,只是开始阶段,传输完成了,异常处理还差一些,遇到了多如牛毛的问题,关键的是这些,其他的都想出了解决办法
      

  7.   

    每次通信时候建一个Socket就行了。通信完毕后自动将Socket关闭。服务器端最好使用多线程,即每个连接的客户端建立一个线程,客户端下线后,服务器端将该线程Abort();