2012-10-07 5 views
0

Ice Cream Sandwich에서 Jelly Bean으로 업그레이드 한 후 클라이언트 (Galaxy Nexus)와 사용자 정의 서버 사이에 타이밍 문제가있는 것으로 보입니다. 여기에 일반적인 흐름은 다음과 같습니다소켓 닫기 타이밍

  1. 클라이언트는
  2. 서버가 수락 새 스레드를 시작, HTTP 헤더와 200 OK로 응답 서버에 소켓, 문제 HTTP GET을 엽니 다.
  3. 서버가 (이진) 파일을 소켓에 씁니다.
  4. 클라이언트는 소켓에서 데이터를 읽고 파일에 저장합니다. 서버 스레드 후
  5. 는 소켓을 닫고, 모든 데이터를 기록하고, 이것은 젤리 빈 업데이트에 앞서 지난 몇 개월 동안 잘 작동했다

종료합니다. 업데이트 이후 바이너리 전송은 약 70 %의 시간 동안 성공합니다. 나머지 30 %는 'serverSocket.getInputStream(). read'가 스트림의 끝에 도달했음을 나타내는 -1을 반환하면 에 실패합니다. 아무런 데이터도 읽지 않았고 오류 예외는 발생하지 않았으며 logcat에는 아무 것도 없었습니다.

5 단계에서 서버 동작을 변경하면 타이밍 문제가 발생할 수 있습니다. 관찰 된 문제로 쓰레드가 스레드를 닫고있었습니다. 내가 소켓 닫기를 제거하고 쓰기 후에 스레드를 종료하고 OS가 결국 소켓을 닫게하면 모든 시간이 작동하는 것처럼 보입니다.

성공적인 케이스와 실패한 케이스에서 패킷을보기 위해 tcpdump와 WireShark를 사용했습니다. 실패한 경우에는 소켓이 수 밀리 초 안에 닫히고 성공한 경우 소켓이 닫히는 데는 4 분의 1 초 이상 걸립니다. 이것의 그물은 우리가 소켓 클로징에서 발생하는 지연이 성공을위한 우리의 기회를 향상 시킨다는 것입니다.

누구든지이 문제를 일으킬 수있는 것에 대한 제안이나 문제의 범위를 좁히는 방법에 대한 제안이 있으면 언제든지 회신 해주십시오. 필요한 경우 코드 샘플을 추가 할 수 있습니다.

+0

수정 된 답변보기 – Luis

답변

-1

서버가 연결 닫기를 요청하면 소켓이 즉시 닫히는 것처럼 보입니다. 아마 기본 오크통의 시간이 버전 사이에 변경되었습니다 ???

사용하여 소켓 링거의 시간을 설정하십시오 :

socket.setSoLinger(boolean on, int timeout); 

일부 데이터는 여전히 전송 대기중인 경우는 수로 전에 약간의 대기 시간 서버를 가지고. 이것이 해결되지 않으면

, 당신은에 위의 흐름을 변경할 수 있습니다

...

4.Client 소켓에서 데이터를 읽고 파일에 저장합니다.

5. 클라이언트가 서버에 확인을 보냅니다.

6. 서버 연결이 끊어졌습니다.

--EDITED-- 닫는 확인을 위해 여행 추가 TCP 데이터 패킷없이 위를 실현하려 gracefull 방법은 다음과 같습니다

소켓에 서버 마무리 쓰기 호출 할 때 :

socket.shutdownOutput(); 

때를 클라이언트 socket.read은() -1 반환, 클라이언트는 호출

socket.close(); 

이것은 클라이언트가 모든 데이터가 센되었다는 통보되는 것을 보장한다 t 및 보낸 사람은 소켓 클로저 프로토콜이 완료 될 때까지 기다립니다.

+0

응답 해 주셔서 감사합니다. 우리는 아무런 차이가없는 잔소리를 시도했다. 그것은 우리의 재 시도 코드를 증명하는 것을 도왔습니다! 확인을 추가하는 것은 우리가 피하려고하는 것입니다. 우리가해야한다면 우리는 이제는 다른 해결책을 추구 할 것입니다. – Dent

+0

"socket.setTcpNoDelay()"를 시도해 보셨습니까? – Luis

+0

setTcpNoDelay()는 아무 효과가 없다고 생각합니다. 우리의 테스트 케이스는 작고 PSH가있는 단일 TCP 패킷에 포함됩니다. 또한 HTTP에 대한 우리의 이해는 서버가 먼저 연결을 닫아야한다는 것을 의미합니다. 제안 된 해결책에 반대하지는 않지만 표준 (?)을 충족하지 못합니다. 아직도 우리의 구현 또는 다른 경우를 이해하려고 노력. – Dent