这是我的课程设计题.
    这两天想了想,很多细节上的问题,都有很多不同的解决方案,不好选择,所以这里跟大家讨论讨论.
    
    1.端口的问题
       a.使用两个端口(30,31),模拟ftp,31端口接收命令(UDP数据报),30端口传数据(如文件,文件列表...)
         为每一个客户启动一个线程(读写文件),这些线程读取和接收的数据都是通过30端口的.
         
       b.使用一个命令接收端口(31),多个数据端口.
         客户端连接服务器时,首先发命令给31,服务器执行命令启动一个线程,在这里线程里开一个端口,专门
         为此客户端服务(包括命令与数据).
         除了第一个命令,其他都是与专用端口通信的.       c.使用nio的非阻塞通信 + 两个端口
    
       d.使用nio的非阻塞通信 + 命令端口,多数据端口    2.数据报校验,重发的问题
       如何支数据报进行校验? 是不是在网络传输过程中,数据报里的数据有可能发生改变??       -----------------------------华丽的分割线---------------------------------       
       (以下是关于重发的)       a.服务器或客户端每收到一个数据报,都向对方回发一个确认数据报(确认数据报只发一次),没发收到确认
         包,则认为丢包,重发.       b.超时机制.客户端接收数据,如果t时间内没有收到数据报,则认为丢包,向服务器发数据报请重发.       c.缓存机制.每次收到n个包才执行一次文件写操作,在写之前,对这n个包进行顺序检查,发现丢失了,则请求对方
         重发.    3.并发的问题
       a.用户a在上传文件f,文件f未上传完成之前,用户b执行dir命令,列出未完成上传的文件.       b.情景同上,不列出未完成上传的文件.       c.如果采用a方案,用户b执行 get f ,要怎么处理?(一个线程在写文件,一个线程同时读文件)
 以上都是我想了的方案了,与大家讨论,或者有更好的方案,请不吝赐教.
             
             
             
             

解决方案 »

  1.   

    UDP协议,传输数据,不具有可靠性。
    大数据量的可靠传输,推荐采用TCP协议。UDP实现文件传输,并且还是C/S架构的,可能要复杂一些。楼主借鉴FTP协议的思想,控制信息和数据信息采用不同的端口进行传输,这是个很好的想法。但是,这就要求,在UDP层上面,要有两套相关的协议生成。控制信息,采用30端口进行交互,可以采用命令行的形式进行交互。
    命令由UTF-8编码的文本构成,由换行符作为命令间的分隔符。
    每个命令都分别由一个UDP报文来承载。数据信息,采用31端口进行收发,采用二进制信息的形式进行传输。由于文件传输的整个过程中,命令信息起着举足轻重的作用,
    所以,针对命令信息的报文,要有差错处理和重传机制。
    由于一个命令一个报文,所以,命令报文不用校验。
    只采用超时重传机制确保命令的请求和应答准确的到达对方。30端口的通信内容包括:文件列表,上传下载文件,检测文件丢失的报文,等等。
    31端口的通信内容只有文件的二进制信息。
    至于文件的大小,报文的大小,共有多少个报文,这些信息统一由30端口进行交互。发送过程:
    1.由命令行将文件的名称,大小,分段大小,传输给接收端。
    2.接收端收到命令,将文件信息绑定到31端口,准备接收。
    3.发送端向接收端的31端口,发送文件信息(所有数据的报文)。
    4.发送端发送检测命令,得到丢失的数据报文编号,进行重传。
    5.接收端接收检测命令,检查所有数据报文的ID号,找到丢失的数据报文ID,返回给发送端。
    6.由第4步、第5步相互配合,完成文件的传输过程。注意:
        A.接收端在31端口数据接收时,要将数据写入文件,但报文ID要保留在内存,留作检测丢包。
        B.发送端在发送数据报文之前,最好要先测试一下,当前网络环境中,允许报文的最大长度是多少。
        C.数据的收发如果采用动态滑动窗口,或者,较为频繁的确定数据的可靠性,就失去UDP的特性了,
          而且,系统复杂性和开销也会加大,所以,本文采用尽量少的次数进行可靠性校验。
        D.接收端,在接受文件数据的时候,要先将数据保存到一个临时文件(临时文件也在硬盘上),
          等文件的所有数据都传输完毕后,在将已传输的文件移动到正确的位置上,
          这样可以保证,楼主所谓的并发处理当中的一些问题,等到解决。
        E.是否使用nio都可以,关键是能够实现需求的功能。
      

  2.   

    使用31端口收发数据,并不是我的意思,而是参照FTP协议的做法。
    FTP协议中,20端口,作为控制信息的交互端口,以命令行形式进行交互。
    主动模式下,21端口作为数据收发的端口,传送文件信息。(当然,可以分为二进制和文本两种数据进行传送)
    被动模式下,数据收发端口,由服务端分配一个其他端口,进行数据传输。至于区分不同用户数据,可以通过创建用户Session数据的方式,识别不同用户,
    不过,编程复杂度可能会大一些。
    最简单的办法是,使用客户端连接过来的Socket内容来确定匿名用户,
    服务端如果遇到连接过来的Socket内容与之相同,就进行该用户的相关操作,包括数据传输和命令执行。