2012-02-08 2 views
15

Java에서 DatagramPacket을 사용하는 경우 byte[1024*1024] 버퍼가 있다고 가정합니다. 송수신 할 때 DatagramPacket에 전달하면 전체 메가 바이트를 읽을 때까지 Java가 DatagramPacket 블록에 대한 호출을 수신합니까?Java DatagramPacket (UDP) 최대 전송/recv 버퍼 크기

Java가 분할 할 것인지, 아니면 삭제되는 전체를 보내려고하는지 묻습니다.

일반적으로 크기 제한은 UDP 패킷의 경우 약 64KB이지만, Java API가 바이트 배열을 허용하기 때문에 궁금합니다. 최대 용량 인 경우 엄청난 크기가 삭제되거나 분할되어 다시 어셈블됩니다.

Java 호출에서 사용할 수있는 최대 데이터 페이로드는 어떤 API 호출에서 나옵니까? 나는 IPv6도 점보 프레임을 가지고 있다고 들었지만 UDP가 헤더 스펙을 정의했기 때문에 DatagramPacket (또는 DatagramSocket)을 지원합니까?

답변

23

DatagramPacket은 UDP 기반 소켓의 단순한 래퍼이므로 일반적인 UDP 규칙이 적용됩니다.

64KB는 완전한 IP 데이터 그램의 이론상 최대 크기이지만 576 바이트 만 라우팅되도록 보장됩니다. 주어진 네트워크 경로에서 최소 전송 단위가 가장 작은 링크가 실제 한계를 결정합니다. (1500 바이트, 더 적은 헤더가 일반적인 최대 값이지만 헤더를 몇 개 예측하여 약 1400 바이트로 메시지를 제한하는 것이 가장 안전합니다.)

MTU 제한을 초과하면 IPv4가 자동으로 데이터 그램을 프래그먼트로 분해하고 마지막에 다시 어셈블하지만 단 64 킬로바이트까지만 조각이 만들어지면 가능합니다. 조각이 손실되거나 장치가 조각을 좋아하지 않는다고 판단하면 전체 패킷이 손실됩니다.

위에서 언급 한 것처럼 경로의 MTU가 무엇인지를 미리 알 수 없습니다. 알아내는 실험을위한 다양한 알고리즘이 있지만 많은 장치가 필요한 표준을 적절하게 구현 (또는 의도적으로 무시)하지 않으므로 시행 착오가 발생합니다. 또는 메시지 당 1400 바이트를 추측 할 수 있습니다.

오류로 인해 OS가 허용하도록 구성된 것보다 많은 바이트를 보내려고하면 EMSGSIZE 오류 또는 이와 동등한 오류가 발생합니다. 그보다 적게 보내지 만 네트워크가 허용하는 것보다 많으면 패킷이 사라집니다.

+1

실제로 네트워크를 통해 IPv4에 대해 보장되는 MTU는 68 바이트 - 호스트가 처리해야하는 최소값은 576입니다. 어느 쪽이든, 그러한 작은 MTU는 실제로 매우 특이합니다. – lxgr

+0

패킷 크기가 64KB를 초과하면 다른 프로토콜을 사용하게됩니까? –

+0

@PhaniRahul : 프로토콜이 분할을 투명하게 처리하고 데이터를 필요한만큼의 패킷으로 만들어 주신 것을 감사드립니다. 실용적인 프로토콜을 사용하면 패킷 크기가 커질 지 의심 스럽습니다. :) –

-1

@ Mihai Danila. 위의 답변에 댓글을 추가 할 수 없기 때문에 회신 섹션에 글을 남기는 이유입니다.

MTU 크기에 대한 대답을 계속하면서 실제로는 NetworkInterface.getMTU()-40을 사용하여 버퍼 크기를 DatagramSocket.setSendBufferSize()으로 설정하려고합니다. 따라서 getSendBufferSize()에 의존하지 않으려 고합니다. 다른 플랫폼에서 다른 창 크기와 일치하며 이더넷에서 보편적으로 허용됩니다 (잠시 전화 접속을 무시함). Windows에서 1450 바이트 (1500-20-20)로 하드 코드하지 않았으므로, MTU 크기는 일반적으로 1500입니다. 그러나 Windows 플랫폼의 자체 창 크기는 8192 바이트이지만 SO_SNDBUF를 < MTU로 설정하면 믿을 수 있습니다. 나는 네트워크/IP 계층에 덜 부담을주고 있으며 라우터와 수신기에 대한 모든 홉 (hop)에 대해 약간의 오버 헤드가 있습니다. 따라서 네트워크를 통해 대기 시간을 줄입니다.

마찬가지로 수신 버퍼의 경우 최대 64K 또는 65535 바이트를 사용하고 있습니다. 이 방법으로 내 프로그램은 다른 창 크기를 사용하는 다른 플랫폼에서 이식 가능합니다.

괜찮은 것 같니? 차이점을 측정하기위한 도구를 구현하지는 않았지만, 그 차이점을 근거로 사례를 가정합니다.

+0

작은 버퍼 크기를 설정할 필요가 없습니다. 당신은 '네트워크 레이어의 IP 레이어 부담을 줄이지 않고'또는 '대기 시간을 줄이는 것'이 아닙니다. 그것을 크게 설정하거나, 자신이하는 일을 모를 경우 그냥 두십시오. 그러나 너무 큰 것을 보내지 않도록하십시오. UDP에는 '창 크기'가 없습니다. MTU를 의미합니까? – EJP

+0

@EJP. 단편화로 인해 네트워크/라우터에 오버 헤드가 추가된다고 분명하게 언급되는 웹에 많은 게시물이 있습니다. 예를 들어 http://pedrotrigueira.net/?page_id=163을 확인하십시오. SO_SNDBUF <= MTU의 크기를 설정하면 분열과 재 조립의 오버 헤드를 피할 수 있습니다. 당신은 UDP가 플랫폼 계층의 윈도우 크기를 처리해야하지만, 패킷이 플랫폼의 윈도우 크기보다 크다면 전송 계층으로 잘려나 간다. 따라서 64K 패킷을 보낼 수 없습니다. – Ashley

+1

'SO_SNDBUF <= MTU'를 설정하면 더 큰 데이터 그램을 보내는 것을 막을 수 있습니다. 그러나 UDP가 허용되는 크기의 UDP 데이터 그램을 버퍼링하지 못하게하여 송신 코드를 과도하게 차단할 수 있습니다. 데이터 그램의 크기를 결정하는 것은'send()'*의 크기이며, * EJP