2011-08-10 2 views
6

나는 많은 웹 사이트와 튜토리얼 (및 문서)을 방문했지만 아직 답변이없는 질문이 하나 있습니다. UDP 패킷이 도착하면 socket.receive (...)를 실행하지 않을 때 어떻게됩니까? socket.receive (...)를 호출하거나 완전히 손실 될 때까지 어떻게 든 버퍼링됩니까?DatagramSocket에서 실제로 수신하지 않는 경우 패킷이 삭제됩니까?

또한 안드로이드의 DatagramSocket 구현은 스레드 안전성을 의미하며 소켓을들을 때 소켓에 쓸 수 있는지 여부를 결정합니다.

답변

9

커널 네트워크 스택은 소켓 당 수신 버퍼을 유지합니다. setsockopt(2) 시스템 호출에 대한 옵션으로 SO_RCVBUF 옵션을 사용하여 크기를 제어 할 수 있습니다 (Java API가 무엇인지 알아야합니다).

들어오는 패킷은 버퍼에 충분한 공간이있는 한 커널에 대기합니다. 애플리케이션이 특정 시점에 "수신"기능을 실행하는 데 필요하지 않은 것은 입니다.이 아닙니다. 응용 프로그램이 패킷을 충분히 대기열에서 제외 (즉, 읽기)하지 않으면 버퍼가 오버플로되고 커널이 패킷을 삭제하기 시작합니다. 리눅스 (일반적으로 Unix)에서는 netstat -s 명령을 사용하여 패킷 수를 볼 수 있어야합니다.

이 버퍼는 패킷이 떨어질 수있는 유일한 장소가 아닙니다. NIC 메모리에 충분한 공간이 없으면 하드웨어가 패킷을 삭제할 수 있습니다. 그런 다음 커널이 너무 많아서 일반 네트워크 입력 대기열을 처리하지 않으면 장치 드라이버가 패킷을 삭제할 수 있습니다. 이 메시지를 전달하려면 심각한 메시지 요금이 필요합니다.

TCP는 총 시퀀싱 및 필요한 경우 재전송을 통해이 모든 것을 처리하려고 시도합니다. UDP는 베어스 뼈가 "보내고 잊어 버린"것이므로 연결된 UDP 소켓의 두 번째 send(2)에서 오류가 발생하는 경우와 ICMP이 제대로 작동하는 경우에만 예외입니다.

결론은 패킷이 버퍼링되지만 지점까지 버려지고 폐기된다는 것입니다.

+1

당신에게 명성! 안드로이드 워드 프로세서를 확인했는데 기본 소켓 버퍼 크기는 4098 바이트입니다. 이것은 소켓 개념을 정말로 분명하게 만듭니다. – LordTwaroog

관련 문제