请问基于C/S下的局域网文件传输,在客户端采用多线程下载一个文件的时候,socket流那里应该做什么处理~服务器先从硬盘读取文件数据,然后向socket流写入数据,客户端启动多个线程和server连接,server这边要怎么去处理?服务器用DataInputStream流先读文件,再用DataOutputStream写入socket流中,客户端的多线程代码应该没问题,在本机上直接读文件不经过socket流写入的时候再写入到别的位置的时候能正常运行,现在是经过了socket流后出现问题了~新手求教~

解决方案 »

  1.   

    现在是经过了socket流后出现问题了
    发点代码,顺便把异常贴出来
      

  2.   

    代码只发主要部分吧~有的无关紧要(个人认为~),先是server这边接收请求和向socket写入的数据,下面的代码中index为从客户端接收到的请求索引值,每次客户端请求下载后就服务器就由下面的代码进行读写传送dos = this.getDataOutputStream(socket);
    brf = new BufferedRandomAccessFile((String) ServerFrame.jt4
    .getValueAt(index, 0), "rw");                        // 用带缓冲的RandomAccessFile读取硬盘数据 long length = ((File) ServerFrame.list.get(index))    //读取要下载的文件的长度
    .length(); dos.writeLong(length); dos.flush(); byte[] buf = new byte[8192]; System.out.println("right here");
    int check = 0; while (true) {
    int read = 0;
    read = brf.read(buf);
    if (read == -1) {
    break;
    }
    dos.write(buf, 0, read);
    }
    dos.flush();
      

  3.   

    再到客户端发送请求这里,收到服务器发来的文件长度后进行分片,index是选择的文件索引值,发送请求,jfc是个JFileChooser~,serverIpAndPort有服务器的IP值和端口,5表示把文件分多少片下载
    dos = this.getDataOutputStream(socket);
    dos.writeInt(index);
    dos.flush(); // 文件索引
    ois = this.getObjectInputStream(socket);
    dis = this.getDataInputStream(socket);
    long length = dis.readLong(); // 读取要下载的文件的总长度  SpiltFile sf=new
     SpiltFile(serverIpAndPort,f,5,length,jfc);

     sf.start();
      

  4.   

    [code=SpiltFile.java]
    public class SpiltFile extends Thread { private long[] StartPos;
    private long[] EndPos;
    private int count;
    private DataOutputStream output;
    private boolean Stop = false;
    private File f;
    private DowndSubThread downSubThread[];
    private long length;
    private JFileChooser jfc;
    private ServerIPAndPort serverIpAndPort; public SpiltFile(ServerIPAndPort serverIpAndPort,File f,int count,long length,JFileChooser jfc) throws InterruptedException {
    this.count = count;
    this.length=length;
    this.jfc=jfc;
    this.f=f;
    this.serverIpAndPort=serverIpAndPort;
    } public void run() {
    try { StartPos = new long[count];
    EndPos = new long[count]; for (int i = 0; i < StartPos.length; i++) {
    StartPos[i] = (long) (i * (length / StartPos.length));
    }
    for (int i = 0; i < EndPos.length - 1; i++) {
    EndPos[i] = StartPos[i + 1];
    }
    EndPos[EndPos.length - 1] = length; DowndSubThread downSubThread[] = new DowndSubThread[count]; 

    for (int i = 0; i < StartPos.length; i++) { downSubThread[i] = new DowndSubThread(serverIpAndPort,f,
    jfc.getSelectedFile().getPath(), StartPos[i],
    EndPos[i], i);
    downSubThread[i].start(); } boolean breakWhile = false;
    while (!Stop) {
    breakWhile = true;
    for (int i = 0; i < StartPos.length; i++) {
    if (!downSubThread[i].DownOver) {
    breakWhile = false;
    break;
    }
    }
    if (breakWhile)
    break;
    }
    System.out.println("文件下载完毕");
    } catch (Exception e) {
    e.printStackTrace();
    }
          }
    }
    [/code]
      

  5.   

    换个新号上代码~超过3次回复~
    [code=Java]
    public class DowndSubThread extends Thread { public long nStart, nEnd;
    private int id;
    private boolean Stop = false;
    public boolean DownOver = false;
    private File f;
    private GetFileDown getFile;
    private Socket socket;
    private ServerIPAndPort serverIpAndPort;
    private String ip;
    private int port; public DowndSubThread(ServerIPAndPort serverIpAndPort, File f, String savePath, long nStart,
    long nEnd, int id) throws IOException {
    this.f = f;
    this.nStart = nStart;
    this.nEnd = nEnd;
    this.id = id;
    this.serverIpAndPort=serverIpAndPort;
    this.getFile = new GetFileDown(savePath, nStart);
    } public void run() {
    while (nStart < nEnd && !Stop) {
    try {

    //获取和服务器的连接

    ip = serverIpAndPort.getIp();
    InetAddress ipServer = InetAddress.getByName(ip); port = Integer.parseInt(serverIpAndPort.getPort()); socket = new Socket(ipServer, port); DataInputStream dis = new DataInputStream(
    new BufferedInputStream(socket.getInputStream()));    
        //读取socket中的数据写入硬盘 byte[] b = new byte[8192];
    int Read;
    while ((Read = dis.read(b, 0, 8192)) > 0 && nStart < nEnd
    && !Stop) {
    nStart += getFile.write(b, 0, Read);

    }
    DownOver = true;
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }}[/code]
      

  6.   


    public class GetFileDown implements Serializable {
    BufferedRandomAccessFile getFile;
    long seekPos; public GetFileDown(String savePath, long seekPos) throws IOException {
    getFile = new BufferedRandomAccessFile(savePath, "rw");
    this.seekPos = seekPos;
    getFile.seek(seekPos);
    }
    public synchronized int write(byte[] b, int nStart, int Length) throws IOException {
    int read = -1;
    try {
    getFile.write(b, nStart, Length);
    read = Length;
    } catch (IOException e) {
    e.printStackTrace();
    }
    return read;
    }
    }
      

  7.   

    现写的。讲究看吧。你的结构有点乱。public class Main {    public static void main(String[] args) throws Exception {
            final int totalParts = 5;
            new Thread() {            @Override
                public void run() {
                    ServerSocket ss = null;
                    try {
                        ss = new ServerSocket(8080);
                        for (int i = 0; i < totalParts; i++) {
                            new Thread(new Send(ss.accept())).start();
                        }
                    } catch (Exception ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        if (ss != null) {
                            try {
                                ss.close();
                            } catch (IOException ex) {
                                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                }
            }.start();
            Thread.yield();
            new Down("localhost", 8080, "c:\\test.png", totalParts).startDown(new File("c:\\test01.png"));
        }    public static void closeIO(Closeable io) {
            if (io != null) {
                try {
                    io.close();
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }    public static class Down implements Runnable {        public Down(String host, int port, String requestFile, int totalParts) {
                this.host = host;
                this.port = port;
                this.requestFile = requestFile;
                this.totalParts = totalParts;
                part = new AtomicInteger(totalParts);
            }        public void startDown(File localFile) throws FileNotFoundException, InterruptedException {
                try {
                    fileWrite = new RandomAccessFile(localFile, "rw");
                    Thread[] ts = new Thread[totalParts];
                    for (int i = 0; i < ts.length; i++) {
                        ts[i] = new Thread(this);
                        ts[i].start();
                    }
                    for (int i = 0; i < ts.length; i++) {
                        ts[i].join();
                    }
                } finally {
                    closeIO(fileWrite);
                }
            }        public void run() {
                Socket s = null;
                try {
                    s = new Socket(host, port);
                    DataOutputStream send = new DataOutputStream(s.getOutputStream());
                    /* 写入头 */ {
                        send.writeUTF(requestFile);
                        send.writeInt(totalParts);
                        send.writeInt(part.getAndDecrement());
                        send.flush();
                    }
                    DataInputStream read = new DataInputStream(s.getInputStream());
                    long fileLength = read.readLong();
                    synchronized (this) {
                        if (fileLength != fileWrite.length()) {
                            fileWrite.setLength(fileLength);
                        }
                    }
                    long seek = read.readLong();
                    byte[] buff = new byte[128 * 1024];
                    for (int i = read.read(buff); i >= 0; i = read.read(buff)) {
                        synchronized (this) {
                            fileWrite.seek(seek);
                            fileWrite.write(buff, 0, i);
                        }
                        seek += i;
                    }
                } catch (Exception ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    try {
                        s.close();
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            private String host;
            private int port;
            private String requestFile;
            private int totalParts;
            private RandomAccessFile fileWrite;
            private AtomicInteger part;
        }    public static class Send implements Runnable {        public Send(Socket s) {
                this.s = s;
            }        public void run() {
                FileInputStream fileRead = null;
                try {
                    DataInputStream read = new DataInputStream(s.getInputStream());
                    DataOutputStream send = new DataOutputStream(s.getOutputStream());
                    /* 每部分文件的最大长度 */
                    long x = 0;
                    /* 计算并发送头 */ {
                        File f = new File(read.readUTF());
                        long fileLength = f.length();
                        x = fileLength / read.readInt();
                        long seek = x * (read.readInt() - 1);
                        send.writeLong(fileLength);
                        send.writeLong(seek);
                        send.flush();
                        fileRead = new FileInputStream(f);
                        fileRead.skip(seek);
                    }
                    byte[] buff = new byte[128 * 1024];
                    for (int i = fileRead.read(buff); i >= 0; i = fileRead.read(buff)) {
                        /* 如果刚刚读完或者读超了,则写入合理的长度,并退出 */
                        if (x <= i) {
                            send.write(buff, 0, (int) (x));
                            break;
                        } else {
                            send.write(buff, 0, i);
                        }
                        x -= i;
                    }
                } catch (Exception ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    try {
                        s.close();
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    closeIO(fileRead);
                }
            }
            private Socket s;
        }
    }