2017-11-27 2 views
0

this 가이드에 따라 Java NIO 소켓 채널을 사용하여 파일을 보내려고했습니다. 그것은 잘 작동합니다. 나는 파일 목록을 보내는 방법을 수정했다. 기본적으로, 나는 파일 목록을 통해 반복하고 위에서 언급 한 가이드에서 이미 구현 된 메소드를 호출한다. "Address already in use"오류가있어서 FileSender 클래스의 소켓 닫기 라인에 주석을 달았습니다. 그 후 코드에 오류가 없었습니다. 프로그램이 중간에 멈춘 것 같습니다. 이 문제를 어떻게 해결합니까? 문제를 해결할 더 좋은 방법이 있습니까? NJava 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

코드와 수신자 코드를 공유하여 원격 지점 (수신기)에서 발생한 상황을 확인할 수 있습니까? –

+0

@JorgeOmarMedra 코드를 추가했습니다. – Arunwij

+0

"FileReceiver.java'에서"Address already in use "예외가 발생합니까? Exception 타입은'BindException'입니까? –

답변

0

당신 수신자가 언제 멈출지를 알 수 있도록 파일 앞쪽에 길이와 아마도 이름을 보내도록 eed했다. 리시버는 정확히 정확히 많은 바이트만을 읽어야하며, 마지막으로 읽을 때 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() 
} 

다시 말하면 위에서 설명한대로 수정해야 할 것입니다.

관련 문제