2017-11-27 5 views
0

Ich habe versucht, Dateien mit Java NIO Socket-Kanäle nach this Guide zu senden. Es funktioniert gut. Ich habe die Methode geändert, um die Liste der Dateien zu senden. Im Grunde gehe ich durch die Dateiliste und rufe die Sendemethode auf, die bereits in der oben erwähnten Anleitung implementiert wurde. Es gab einen Fehler "Adresse wird bereits verwendet", also habe ich die Socket-Schlusslinie in der FileSender-Klasse kommentiert. Danach gab es keinen Fehler im Code. Scheint das Programm in der Mitte stecken zu bleiben. Wie löse ich dieses Problem? Gibt es einen besseren Weg, das Problem zu lösen?Senden Sie mehrere Dateien mit Java NIO SocketChannel

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(); 
    }*/ 
} 
+0

könnten Sie Ihren Code und den Empfängercode teilen, um zu sehen, was mit dem entfernten Punkt (Empfänger) passiert ist. –

+0

@JorgeOmarMedra Ich habe den Code hinzugefügt. – Arunwij

+0

Die Ausnahme "Adresse bereits verwendet" entsteht in 'FileReceiver.java'? und der Ausnahmetyp ist 'BindException'? –

Antwort

0

Sie n um die Länge und wahrscheinlich den Namen vor der Datei zu senden, damit der Empfänger weiß, wann er anhalten soll. Der Empfänger muss sicherstellen, dass nur genau so viele Bytes gelesen werden, was eine Reduzierung des limit beim letzten Lesen erforderlich macht. Außerdem sind die Kopierschleifen falsch:

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

Dies funktioniert nicht unbedingt am Ende des Streams korrekt. Es sollte sein:

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

merkt erneut, dass sie wie oben beschrieben weiter modifiziert werden müssen.

Verwandte Themen