簡體   English   中英

使用Java NIO SocketChannel發送多個文件

[英]Send multiple files using Java NIO SocketChannel

我已嘗試根據指南使用java NIO套接字通道發送文件。 工作正常。 我修改了發送文件列表的方法。 基本上,我循環瀏覽上述指南中已實現的文件列表和調用發送方法。 出現錯誤“地址已在使用中”,因此我在FileSender類中注釋了套接字結束行。 之后,代碼中沒有錯誤。 程序似乎卡在中間。 我該如何解決這個問題? 有沒有更好的方法來解決問題?

主Java

public static void main(String[] args) throws IOException, InterruptedException{
    RunningConfiguration.run();

    List<File> files = new <File>ArrayList();

    File a = new File("pics/city.jpg");
    File b = new File("pics/desert.jpg");
    File c = new File("pics/flower.jpg");
    File d = new File("pics/night.jpg");

    List<Node> nodes = RunningConfiguration.getNodeList();

    ListIterator li = nodes.listIterator();

    while(li.hasNext()){
        Node node = (Node)li.next();
        FileSender.send(node, files, "pics/received/");
    }

}

FileSender.Java

public class FileSender {
private final InetSocketAddress fileSocketAddress;
private final File file;

public FileSender(InetAddress inetAddress, File file) throws IOException{
    this.fileSocketAddress = new InetSocketAddress(inetAddress,RunningConfiguration.FILE_PORT);
    this.file = file;
}

public static void send(InetSocketAddress inetSocketAddress, File file) throws IOException{
    FileSender nioClient = new FileSender(inetSocketAddress.getAddress(),file);
    SocketChannel socketChannel = nioClient.createChannel();
    nioClient.sendFile(socketChannel);
}

public static void send(Node to, File file) throws IOException{
    FileSender nioClient = new FileSender(to.getSocketAddress().getAddress(),file);
    SocketChannel socketChannel = nioClient.createChannel();
    nioClient.sendFile(socketChannel);
}

public static void send(Node to, File file,String filepath) throws IOException{
    FileSender nioClient = new FileSender(to.getSocketAddress().getAddress(),file);
    SocketChannel socketChannel = nioClient.createChannel();
    nioClient.sendFile(socketChannel);
}

public static void send(Node to,List<File> files,String filepath) throws IOException{
    ListIterator ltr = files.listIterator();
    while(ltr.hasNext()){
        File file = (File) ltr.next();
        FileSender nioClient = new FileSender(to.getSocketAddress().getAddress(),file);
        SocketChannel socketChannel = nioClient.createChannel();
        nioClient.sendFile(socketChannel);
    }
}
public SocketChannel createChannel() {
    SocketChannel socketChannel = null;

    try {
        socketChannel = SocketChannel.open();
        SocketAddress socketAddress = this.fileSocketAddress;
        socketChannel.connect(socketAddress);
        System.out.println("Connected..Now sending the file");
    } catch (IOException e) {
        e.printStackTrace();
    }
    return socketChannel;
}


public void sendFile(SocketChannel socketChannel) {
    RandomAccessFile aFile = null;
    try {
        //File file = new File("data\\web.exe");
        aFile = new RandomAccessFile(this.file, "r");
        FileChannel inChannel = aFile.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        while (inChannel.read(buffer) > 0) {
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();
        }

        Thread.sleep(400);
        System.out.println("End of file reached..");
        socketChannel.close();
        aFile.close();

    } catch (FileNotFoundException e ) { 
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

FileReceiver.java

private String fileName;

public FileReceiver(String fileName) {
    this.fileName = fileName;
}

public static void receive(String fileName) {
    FileReceiver nioServer = new FileReceiver(fileName);
    SocketChannel socketChannel = nioServer.createServerSocketChannel();
    nioServer.readFileFromSocket(socketChannel);
}

public FileReceiver() {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public SocketChannel createServerSocketChannel() {

    ServerSocketChannel serverSocketChannel = null;
    SocketChannel socketChannel = null;

    try {
        System.out.println("File receiver listening at port: " + RunningConfiguration.FILE_PORT);
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(RunningConfiguration.FILE_PORT));
        socketChannel = serverSocketChannel.accept();
        System.out.println("Connection established...." + socketChannel.getRemoteAddress());

    } catch (IOException e) {
        e.printStackTrace();
    }

    return socketChannel;
}

/**
 * Reads the bytes from socket and writes to file
 *
 * @param socketChannel
 */
public void readFileFromSocket(SocketChannel socketChannel) {

    RandomAccessFile aFile = null;
    try {
        aFile = new RandomAccessFile(this.fileName, "rw");
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        FileChannel fileChannel = aFile.getChannel();
        while (socketChannel.read(buffer) > 0) {
            buffer.flip();
            fileChannel.write(buffer);
            buffer.clear();
        }
       // Thread.sleep(1000);
        fileChannel.close();
        System.out.println("End of file reached..Closing channel");
        socketChannel.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }/*} catch (InterruptedException e) {
        e.printStackTrace();
    }*/
}

您需要在文件之前發送長度(可能是名稱),以便接收方知道何時停止。 接收器必須確保只讀取那么多字節,這可能需要減少最后一次讀取的limit 另外,您的復制循環不正確:

while (inChannel.read(buffer) > 0) {
    buffer.flip();
    socketChannel.write(buffer);
    buffer.clear();
}

在流的末尾不一定能正常工作。 它應該是:

while (inChannel.read(buffer) >= 0 || buffer.position() > 0) {
    buffer.flip();
    socketChannel.write(buffer);
    buffer.compact(); // NB compact(), not clear()
}

再次指出,他們將需要如上所述的進一步修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM