2010-04-04 4 views
4

저는 Android에서 네트워킹 응용 프로그램을 코딩하고 있습니다.대기 상태에서 둘 이상의 UDP 데이터 그램 소켓을 갖는 것이 합리적입니까? "동시"패킷이 커널에 의해 삭제되거나 대기 중입니까?

하나의 UDP 포트와 데이터 그램 소켓을 가지고 보내진 모든 데이터 그램을 수신 한 다음이 메시지에 대해 다른 처리 대기열을 갖고 있다고 생각합니다.

대기 상태에서 두 번째 또는 세 번째 UDP 소켓이 있어야하는지 궁금합니다. 일부 메시지는 매우 짧을 것이고 (100 바이트 정도), 다른 메시지는 파일을 전송해야합니다.

내 관심사는 안드로이드 커널이 더 큰 메시지를 처리하는 데 너무 바빠서 작은 메시지를 삭제하겠습니까?

업데이트 는 "후자의 기능은 소켓의 수신 버퍼에 UDP 패킷을 큐 (sock.h에에) sock_queue_rcv_skb()를 호출합니다. 더 이상 공간이 버퍼에 남아 있지 않으면 패킷이 삭제됩니다. 필터링은 TCP와 마찬가지로 sk_filter()를 호출하는이 함수에 의해 수행되며 마지막으로 data_ready()가 호출되고 UDP 패킷 수신이 완료됩니다. "

답변

7

기본 사항을 먼저 알아 보겠습니다.

모든 소켓에는 수신 및 송신 버퍼가 있습니다. 네트워크 하드웨어가 새로운 패킷 의 도착을 알리는 경우 수신 버퍼가 가득차면 패킷이 삭제됩니다. 버퍼 크기는 SO_RCVBUFSO_SNDBUF 소켓 옵션을 통해 제어됩니다 (setsockopt(3) 참조). OS는 몇 가지 기본값을 설정합니다 (그리고 /etc/sysctl.conf 파일이 있습니다).

~$ sysctl -a|grep space 
net.inet.tcp.recvspace=16384 
net.inet.tcp.sendspace=16384 
net.inet.udp.recvspace=41600 
net.inet.udp.sendspace=9216 

는 TCP 및 UDP의 차이점은 이전의 데이터 시퀀싱 및 손실 된 패킷의 재송 플러스 유량 조절을 담당한다는 것이다 (느린 리더 다운 빠른 감속 :이 BSD 시스템에 작가), 후자는 그렇지 않습니다.

그래, UDP를 사용하여 파일을 전송하는 것이 가장 좋지는 않지만 이지만 작동하려면 옵션을 사용하십시오.하나는 TCP의 일부를 재발 명하고 TCP에 대한 재 발명의 오버 헤드를 고려해야합니다. 다시 말하지만, UDP는 일부 패킷 재정렬/손실 (예 : 오디오/비디오 스트림)을 허용 할 수있는 애플리케이션에 가장 적합하다는 것이 일반적입니다.

그렇다면 모든 소켓에는 데이터를 송수신하기위한 별도의 스레드가 필요하다는 오해 된 생각이 있습니다. 이는 사실과 거리가 있습니다. 많은 뛰어난 고성능 네트워크 응용 프로그램이 스레드없이 작성되었지만 비 차단 소켓과 일부 폴링 메커니즘을 사용합니다 (select(2), poll(2), epoll(7) 참조). 질문 자체에

: 응용 프로그램이 소켓에 충분한 공간을 유지하는 것이 너무 바빠서 경우

예, 커널이 패킷을 드롭 수는 '버퍼를받을 수 있습니다. 그러나 각 소켓에는 자체 소켓이 있기 때문에 제어 및 데이터 스트림을 분리하면 도움이됩니다. 개인적으로는 간단한 TCP 서버 설정을 위해 갈 것입니다. 포트에서 수신 대기하고 클라이언트 당 연결을 수락하고 TCP 스트림 상단에 의미있는 프로토콜을 구현하십시오. UDP 및 저수준 프로토콜 상태 머신으로 게임하는 것은 많은 재미를 낳는다는 것에 동의하지만, 이미 완료되었으며 수십 년에 걸친 연구가 TCP 성능 튜닝에 들어갔다. 결국 중요한 것은 응용 프로그램의 안정성 (첫 번째)과 성능 (초)입니다.

희망이 도움이됩니다.

+0

가장 우수한 답변 Nikolai. 나는 지난 밤에 실제로가는 방법이 TCP와 NIO가 될 것이라고 생각하고있었습니다. 내 장치가 너무 많은 스레드를 처리 할 수 ​​없으며 def가됩니다. 들어오는 요청이 많습니다. – Gubatron

+0

아시겠습니까? 대답을 수락 할 수 있습니까? :) –

+0

UDP는 데이터를 실시간으로 업데이트해야하고 재전송 비용을 겪을 수없는 경우에만 유용합니다. 이러한 연결의 예로는 스트리밍 비디오/음악, 대기 시간이 중요한 실시간 게임 또는 수신 청크에서 CRC 체크로 어쨌든 데이터 청크가 확인되는 파일 전송 (FTP)이 있습니다. –

1

UDP는 패킷 수신 순서 나 수신 여부를 보장 할 수 없기 때문에 파일 전송에 좋지 않습니다. 이 문제에 대해 내결함성이있는 전송 계층을 만들려고한다면 TCP/IP를 대신 사용해야합니다.

UDP는 수신 된 패킷을 버퍼링하거나 대기열에 넣지 않습니다. 패킷이 수신되고 데이터를 기다리는 경우 수신합니다. 프로그램이 다른 처리를하고있는 중 패킷이 수신되면 패킷을 전혀받지 못합니다. 따라서 두 개의 "동시 패킷"(두 개는 매우 가깝습니다)을 받으면 각 패킷의 중요한 처리를 수행하는 중 하나를 놓칠 수있는 좋은 기회가 있습니다.

추가 포트가 열려 있으면 어떻게 도움이 될지 모르겠다. 포트 1에서 패킷을 처리하는 중 바쁜 경우 각 포트가 전용 스레드에서 실행되고 있지 않으면보고있는 다른 포트에서 들어오는 모든 패킷을 놓칠 수 있습니다. 패킷을 자신의 버퍼에 빠르게 복사하고 다른 스레드로 전달하여 처리하는 것이 훨씬 좋으므로 리스너 스레드가 가능한 빨리 청취 할 수 있습니다.

+1

내가 보내는 각 파일을 처리하는 스레드를 갖고 싶지 않기 때문에 TCP를 수행 할 수 없습니다. (많은 동시 전송을 생각합니다.) 누락 된 부분을 묻는 간단한 논리를 구현했습니다. 완료 될 때까지 파일이 단단히 작동합니다. 커널에 UDP 버퍼가 있고 한 번 가득 차면 패킷을 버릴 것이라고 읽었습니다. 그렇습니다. UDP 패킷을받는 스레드는 작업 패킷을 처리하는 큐에 처리 스레드가 즉시 저장하므로 UDP 소켓은 가능한 한 많이 사용 가능하며 커널의 UDP 버퍼는 가득 차 있어서는 안됩니다. – Gubatron

+0

UDP에서 패킷이 손실 된 경우를 감지 할 수 없습니다. 당신은 바퀴를 재발견하고 싶어하고, 실패 할 것입니다. – Pentium10

+0

게으른 사람들은 무엇입니까? TCP에 대해 너무 종교적입니다! 모두 당신 때문에 GPRS가 작동하지 않고 Wi-Fi가 느려집니다! –

0

TCP의 흐름 제어는 손실 된 패킷을 줄이는 데 도움이됩니다. 그것의 내결함성은 패킷이 순차적으로 도착할 수있게합니다.

+0

질문은 UDP에 관한 것입니다. – EJP

관련 문제