2012-11-03 1 views
2

이것은 첫 번째 질문입니다. 나 자신을 돕기 위해 수 시간 동안 수색했지만 인터넷에는 해결책이 없다. 내 프로그램은 "System.out.println()"을 삽입 할 때만 실행되며, tcp를 사용하여 큰 파일 (mp3, 5MB)을 전송하려고합니다. 나는 많은 경험이 자바와 함께 일하고 있지만, 이것은 매우 흥미로운 실패이다.네트워크 예외가 System.out.println에 의해 수정되었지만 사용하고 싶지 않습니다.

서버와 클라이언트이 클라이언트

public void receive(int port) { 
     try { 
      ServerSocket s = new ServerSocket(port); 
      Socket socket = s.accept(); 
      BufferedInputStream in = new BufferedInputStream(
        socket.getInputStream()); 
      FileOutputStream fileOut = new FileOutputStream("dateiname.mp3"); 

      startzeit = Calendar.getInstance().getTimeInMillis(); 

      byte[] b = new byte[32]; 
      while (in.available() > 0) { 
       System.out.println(Calendar.getInstance().getTimeInMillis() 
         - startzeit); 
       in.read(b); 
       fileOut.write(b); 
       fileOut.flush(); 
       received += 1; 
      } 
      System.out.println("Feritg"); 
      fileOut.close(); 
     } catch (SocketException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

그리고 서버에 대한 내 코드입니다 128.0.0.1

에 있습니다

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.net.InetAddress; 
import java.net.Socket; 

public class FileTransfer { 
    @SuppressWarnings("resource") 
    public static void send(File datei, InetAddress ip, int port) 
      throws IOException 
     { 
     Socket socket = new Socket(ip, port); 
     BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 
     FileInputStream fileIn = new FileInputStream(datei); 
     while (fileIn.available() > 0) { 
      byte[] b = new byte[32]; 
      fileIn.read(b); 
      out.write(b); 
      out.flush(); 
     } 
     out.close(); 
     socket.close(); 
    } 
} 

그리고 서버

에 의해 적어도 예외 슬로우되었을
Exception in thread "main" java.net.SocketException: Connection reset by peer: socket write error 
at java.net.SocketOutputStream.socketWrite0(Native Method) 
at java.net.SocketOutputStream.socketWrite(Unknown Source) 
at java.net.SocketOutputStream.write(Unknown Source) 
at java.io.BufferedOutputStream.flushBuffer(Unknown Source) 
at java.io.BufferedOutputStream.flush(Unknown Source) 
at FileTransfer.send(FileTransfer.java:20) 
at MainServer.main(MainServer.java:12) 

도와주세요!

답변

2

이 예외는 클라이언트가 예기치 않게 소켓을 종료했음을 의미합니다.

while 루프에서 수표로 available()을 사용하고 싶지는 않을 것입니다. 이 함수는 파일의 총 바이트 수가 아니라 블로킹없이 읽을 수있는 바이트 수만 나타냅니다. 대신 서버에 다음과 같은 내용이 필요합니다.

while (fileIn.read(b) != -1) { ... 

클라이언트에서 유사한 코드를 사용해야합니다.

또한 코드가 32 바이트 미만을 읽는 경우를 처리하지 않습니다. 당신은 정말 수행해야합니다

while ((n = fileIn.read(b))!= -1) { 
    out.write(b, n); 
    ... 

마지막으로, 32 바이트 정말 작은 크기, 당신은 4킬로바이트, 8킬로바이트 또는 더 큰 버퍼를 사용하여 빠른 전송을 얻을 수 있습니다.

+0

또한 서버 측에서 'byte [] b = new byte [32];'행을 이동하십시오. 루프 외부에서 버퍼를 한 번만 할당 할 수 있습니다. –

+0

또한 서버 측에서는 try 블록 내에서 소켓 I/O를 가져야하며 클라이언트 측에서 수행하는 것처럼 SocketException을 포착해야합니다. –

1

바퀴를 재발 명하지 마십시오. Apache Commons IO 라이브러리의 IOUtils.copy(InputStream input, OutputStream output)을 사용하십시오.

관련 문제