【问题标题】:Send multiple files using Java NIO SocketChannel使用 Java NIO SocketChannel 发送多个文件
【发布时间】:2017-11-28 11:53:58
【问题描述】:

我已尝试根据this 指南使用 java NIO 套接字通道发送文件。它工作正常。我修改了发送文件列表的方法。基本上,我遍历文件列表并调用上述指南中已经实现的发送方法。有一个错误“地址已在使用中”,所以我在 FileSender 类中注释了套接字关闭行。之后,代码中没有错误。似乎程序卡在中间。我该如何解决这个问题?有没有更好的方法来解决这个问题?

Main.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();
    }*/
}

【问题讨论】:

  • 你能分享你的代码和接收器代码,看看远程点(接收器)发生了什么。
  • @JorgeOmarMedra 我已经添加了代码。
  • FileReceiver.java 中出现“地址已在使用”异常?异常类型是BindException?

标签: java sockets nio socketchannel


【解决方案1】:

您需要在文件之前发送长度,可能还有名称,以便接收方知道何时停止。接收器必须确保只读取那么多字节,这可能需要减少最后一次读取时的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()
}

再次注意他们需要如上所述的进一步修改。

【讨论】:

    猜你喜欢
    • 2016-10-03
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2013-10-07
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多