자바 소켓을 이용할 파일 입출력 프로그램을 짜는데요 클라이언트에 readUTF에서 EOFException처리때문에 질문드립니다

조회수 4516회

서버 하나에 여러 클라리언트가 접속해서 채팅을 하는 프로그램에

서버가 option을 입력하면 메뉴가 뜨고 파일전송을 선택하면 파일 경로를 입력한 후 접속자 중 누구에게 보낼지 정한 다음 클라이언트 에게 보내고 클라이언트는 받는데요 파일을.

클라이언트가 Y 또는 y를 입력하면 서버에게 "Please send the File"라는 문자열을 보낸 후 서버가 "파일 전송합니다." 문자열을 보내고 바로 파일을 전송하기 시작하고 이와 동시에 클라이언트에서는 "파일 전송합니다."라는 문자열을 받으면 파일을 받기 시작합니다.

클라이언트는 파일을 정상적으로 다 받는데 마지막에 EOFException을 처리하면서 클라이언트가 접속을 끊어버리고 나가버립니다. 밑에 사진은 클라이언트 입니다.

에러 메시지

코드 입니다.

[AServer.java]

                if(c_s.elementAt(i).name.equals(name))
            {                           
                c_s.elementAt(i).dos.writeUTF("파일 전송합니다.");
                //보내기 로직
                fis = new FileInputStream(filePath);
                bis = new BufferedInputStream(fis);
                int len = 0;
                int size = 4096;
                byte[] data = new byte[size];
                while ((len = bis.read(data, 0, 4096)) != -1) {
                    c_s.elementAt(i).dos.write(data, 0, len);
                    c_s.elementAt(i).dos.flush();
                }
                System.out.println("파일 전송 작업을 완료하였습니다.");
                System.out.println("보낸 파일의 사이즈 : " + sendFile.length());

                c_s.elementAt(i).dos.close();
                bis.close();
                fis.close();
                break;
            }
        }
    }

[AClient]

            else if(msgClient.equals("파일 전송합니다."))
            {       
                pln("전송 받기 시작!");
                fos = new FileOutputStream(f);
                bos = new BufferedOutputStream(fos);

                int len = 0;
                int size = 4096;
                byte[] data = new byte[size];

                while ((len = dis.read(data, 0, 4096)) != -1) {
                    bos.write(data, 0, len);
                    bos.flush();
                } 
                System.out.println("파일 수신 작업을 완료하였습니다.");
                System.out.println("받은 파일의 사이즈 : " + f.length());                   
                bos.close();
                fos.close();
                dis.close();
            }

이미지 이름이나 설명을 여기에 넣어주세요.

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 코드를 상당히 길게 적어주셨는데요. 문제라고 생각되는 부분을 요약해서 올려주지 않으시면 읽어보실 분이 거의 없을것 같아요. 그리고 코드는 마크다운 문법에 맞춰서 ```와 ```로 감싸서 올려주셔야 잘 나옵니다. 정토드 2016.4.4 12:14

3 답변

  • 에러가 발생하는 부분이 위에 올려주신 클라리언트 코드에서 어느 부분인지 우선 궁금합니다. 이미지 파일을 보면 readUnsignedShort에서 에러가 발생하는것 같은데요. 올려주신 클라이언트 코드에는 readUnsignedShort를 호출하는 부분이 없네요.

    파일은 정상적으로 다 받아지는게 맞나요? 그렇다면 try/catch로 Exception이 발생하는 부분만 감싸준다면 클라이언트가 처리 안된 Exception때문에 종료되지는 않을것 같은데요.

    • (•́ ✖ •̀)
      알 수 없는 사용자
  • 전체 코드를 알 수가 없어서 추측을 해본다면... 에러는 클라이언트에서 dis.close() 를 호출하였는 데, 그 후에 dis로 부터 또 읽어들이지 않았나 싶네요.

                    System.out.println("파일 수신 작업을 완료하였습니다.");
                    System.out.println("받은 파일의 사이즈 : " + f.length());                   
                    bos.close();
                    fos.close();
                    dis.close(); // 입력스트림 닫음
                }
                // 이 후에 입력스트림으로 부터 무엇인가 읽어서 에러가 난것으로 추측됩니다.
    
  • 먼저 파일을 전송하기 전에 파일의 용량을 보낸 후에 서버는 파일의 내용을 보내는 것이 좋습니다. 클라이언트는 용량정보를 받은 후 그 용량만큼만 read해서 저장 하도록 합니다.

    용량을 보내지 않으면 클라이언트쪽에서는 언제까지 읽어들일지 알수 없는 상태가 되기때문에 계속 정보를 읽어들이려고 시도하게 됩니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)