2013-07-26 4 views
1

클라이언트 - 서버 파일 전송 프로젝트에서 로컬 호스트 테스트를 거의 완료했지만 현재 클라이언트와 서버의 소스 코드는 다음과 같습니다.java 파일 전송 소켓 쓰기 오류

클라이언트 측

public class Client { 

    public static void main(String args[]) { 
     String receiverIP = null; 
     int serverPort = 0; 
     receiverIP = args[0]; 
     serverPort = Integer.parseInt(args[1]); 
     String fileToSend = args[2]; 
     byte[] aByte = new byte[1]; 
     int bytesR; 
     Socket clientSocket = null; 
     BufferedOutputStream bos = null; 
     InputStream is = null; 

     try { 
      clientSocket = new Socket(receiverIP, serverPort); 
      bos = new BufferedOutputStream(clientSocket.getOutputStream());   
      is = clientSocket.getInputStream(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     }  

     if (is != null) {   
      FileOutputStream fos = null; 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      try { 

        File myFile = new File(fileToSend); 
        System.out.println("The file chosen is being sent..."); 
        byte[] mybytearray = new byte[(int) myFile.length()]; 
        FileInputStream fis = null; 

        try { 
         fis = new FileInputStream(myFile); 
        } catch (FileNotFoundException ex) { 
         ex.printStackTrace(); 
        } 
        try { 
         BufferedInputStream bis = new BufferedInputStream(fis); 
         bis.read(mybytearray, 0, mybytearray.length); 
         bos.write(mybytearray, 0, mybytearray.length); 
         bis.close(); 

         return; 
        }catch (IOException ex) { 
         ex.printStackTrace(); 
        } 

       File file = new File("C:\\copy.jpg"); 
       fos = new FileOutputStream(file); 
       bos = new BufferedOutputStream(fos); 
       bytesR = is.read(aByte, 0, aByte.length); 
       do { 
         baos.write(aByte); 
         bytesR = is.read(aByte); 
       } while (bytesR != -1); 
       System.out.println("File transfer successful"); 

       bos.write(baos.toByteArray()); 
       bos.flush(); 
       bos.close(); 
       clientSocket.close(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 
} 

여기

public class Server { 

    public static void main(String args[]) { 

     while (true) { 
      ServerSocket welcomeSocket = null; 
      BufferedOutputStream ToClient = null; 

      try { 
       welcomeSocket = new ServerSocket(3249); 
       System.out.println("The port " + welcomeSocket.getLocalPort() + " is opened and ready for use."); 
       Socket connectionSocket = welcomeSocket.accept(); 

       ToClient = new BufferedOutputStream(connectionSocket.getOutputStream()); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 
} 

서버 측 인 내가 얻을 오류

The file chosen is being sent... 
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.write(Unknown Source) 
    at Client.main(Client.java:44) 
java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at Client.main(Client.java:55) 

나는이 오류가 모든 데이터가 전송되기 전에 서버 소켓을 닫는에 대한 아닙니다 거의 확신하고,이 ByteArray하지만 내 모든 수정 시도에 읽기와 쓰기 과정에 대해 아마도, 헛된했다 내가 의도 한대로 작동하지 않도록 스트림을 잘못 배치했습니다. (copy.jpg 파일이 생성되었지만 스트림이 없습니다.) 어떤 도움도 받으실 수 있습니다.

편집 : 현재 언급 한 것을 잊어 버렸습니다. 무선 인터넷 연결 및 무선 네트워크에 대한 테스트가 신뢰할 수없는 소켓 porgramming에 대해 조금 읽었습니다

답변

0

요 서버 측은 데이터 수신을 기다리지 않습니다. 연결을 허용 한 후 즉시 다음 루프 사이클을 계속합니다. 이로 인해 초기 서버 소켓과 클라이언트 소켓이 가비지 수집되어 닫힙니다.

텔넷을 사용하여이 동작을 확인할 수 있습니다. 텔넷은 일반적으로 서버를 검사 할 때 매우 편리합니다. 서버 시스템 (cmd를 또는 콘솔)에서 명령 프롬프트를 열고 서버에 연결하려면이 명령을 실행

telnet localhost 3249 

그냥 자신의 클라이언트 응용 프로그램처럼, 거의 즉시 연결이 끊어진 후 연결하고 당신이 볼 수 .

해결 방법은 서버 쪽에서 연결을 허용하는 코드에 추가적으로 데이터 수신을위한 코드를 작성해야합니다.

또한 서버 소켓 을 루프 내부가 아닌 루프 앞에 넣어야합니다. 서버 소켓은 단 한 번만 만들어야하며, 그렇게하면 여러 개의 연결을 임의로 허용 할 수 있습니다. 포트가 여전히 사용 중이기 때문에 서버 소켓을 두 번 이상 여는 것은 실패합니다 (이전 서버 소켓이 닫힌 경우에도 포트를 해제하는 데 종종 일부 운영 체제에서 몇 초가 걸립니다).