마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 소켓 파일 전송 문제

0 추천

안녕하세요.

제가 만들고 있는 앱 기능 중에 하나로 파일 전송이 있습니다. 같은 네트워크에 있는 서버와 TCP 통신으로 파일 데이터를 넘겨주는데, 문제는 가끔가다 파일 전송이 뚝 끊기는 경우가 있습니다. 단순히 네트워크 연결이 끊긴 것과는 다르게 TCP 연결이 완료되고 전송할 파일의 정보도 넘어간 다음에 파일의 raw 데이터가 전송될 시간에 몇 KB를 전송하다가 전송이 멈춤니다. 그런데 이 문제가 항시 있는 것이 아니라 잘 전송되는 때도 있다는 것입니다. 그래서 대체 어디가, 어떻게 문제인지 찾을 수가 없어서 질문드립니다.

 

- 클라이언트 부분 (코드의 핵심 부분만 간략해서 올렸습니다.)

// 소켓 설정 및 연결 요청
socket.setSoTimeout(TIMEOUT);
socket.setSoLinger(true, TIMEOUT);
socket.connect(socketAddress, TIMEOUT);

// 파일 데이터 전송
FileInputStream fileInputStream = new FileInputStream(file);
while ((readCount = fileInputStream.read(buffer, 0, buffer.length)) > 0) {
    socket.getOutputStream().write(buffer, 0, readCount);
}

소켓 연결하기 전에 설정과 연결부분 그리고 실제 문제가 생기는 파일 데이터를 전송하는 부분만 올렸습니다.

파일을 전송하는 로직은 파일 데이터를 버퍼에 읽어와서 그 버퍼를 다시 소켓 스트림으로 전송하는 것입니다.

 

- 안드로이드 스튜디오 모니터 네트워크 부분

네트워크 전송 데이터

네트워크 모니터를 보면 조금 전송하다가 전송이 중단 됩니다. 그러나 timeout이나 예외도 없이 멈춰있습니다.

푸르미르 (170 포인트) 님이 2017년 5월 3일 질문
푸르미르님이 2017년 5월 3일 수정

2개의 답변

0 추천
// 소켓 설정 및 연결 요청
socket.setSoTimeout(TIMEOUT);
socket.setSoLinger(true, TIMEOUT);
socket.connect(socketAddress, TIMEOUT);
 
// 파일 데이터 전송
FileInputStream fileInputStream = new FileInputStream(file);
while ((readCount = fileInputStream.read(buffer, 0, buffer.length)) > 0) {
    socket.getOutputStream().write(buffer, 0, readCount);
    socket.getOutputStream().flush(); //<-- flush 시도
}

음.. 해결책이 될지는 모르겠으나

write 다음 라인에 flush를 넣어보세용.

Development Guy (70,570 포인트) 님이 2017년 5월 4일 답변
답변해주신대로 했지만 같은 문제가 발생하네요. ㅜㅜ
0 추천
안녕하세요.

위 코드를 아래처럼 변경해 주세요.

read()가 0이 될수가 있거든요.. -1이 끝까지 읽었다는 것을 나타냅니다.

FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = socket.getOutputStream();
while (fis.read(buffer, 0, buffer.length) != -1) {
   os.write(buffer, 0, buffer.length);
}

그리고, 명시적으로 OutputStream을 close하기 위해서는 socket.getOutputStream()을 해서 나중에 os, bis를 close() 해 줘야 합니다.
mcsong (44,040 포인트) 님이 2017년 5월 5일 답변
...