UDP
UDP
Racket은 UDP(User Datagram Protocol) 데이터그램을 보내고 받기 위한 소켓 API를 제공해요. UDP에 대한 일반적인 정보는 W. Richard Stevens의 TCP/IP Illustrated, Volume 1을 참고하세요.
출처: Racket Reference
본문
이 절에 문서화된 바인딩들은 racket/udp와 racket 라이브러리가 제공하며, racket/base가 제공하는 게 아니에요.
(require racket/udp) ; package: base
(udp-open-socket [family-hostname family-port-no]) → udp?
family-hostname : (or/c string? #f) = #f
family-port-no : (or/c port-number? #f) = #f
procedure
데이터그램을 보내고 받기 위한 UDP 소켓을 만들고 돌려줘요 (브로드캐스팅 허용). 처음에는 소켓이 어떤 주소나 포트에도 바인딩되거나 연결되지 않아요.
family-hostname 또는 family-port-no가 #f가 아니면, 이 인자들에서 소켓의 프로토콜 패밀리가 결정돼요. 소켓은 호스트네임이나 포트 번호에 바인딩되지는 않아요. 예를 들어, 그 인자들은 소켓을 통해 보낼 메시지의 대상 호스트네임과 포트일 수 있으며, 이렇게 하면 소켓의 프로토콜 패밀리가 목적지와 일관되게 보장돼요. 또는 그 인자들은 향후 udp-bind! 호출과 동일할 수 있으며, 이렇게 하면 소켓의 프로토콜 패밀리가 바인딩과 일관되게 보장돼요. family-hostname과 family-port-no 모두 #f가 아니면 안 되는 경우, 소켓의 프로토콜 패밀리는 IPv4예요.
FD_CLOEXEC를 지원하는 Unix와 MacOS 변형에서는 소켓에 그 플래그가 주어져 subprocess가 만든 서브프로세스와 공유되지 않아요.
base 패키지 8.11.1.6 버전에서 변경됨: 운영체제가 지원하는 곳에서 FD_CLOEXEC를 사용하도록 변경되었어요.
(udp-bind! udp-socket hostname-string port-no [reuse?]) → void?
udp-socket : udp?
hostname-string : (or/c string? #f)
port-no : listen-port-number?
reuse? : any/c = #f
procedure
바인딩되지 않은 udp-socket을 로컬 포트 번호 port-no에 바인딩해요. port-no가 0이면 udp-socket은 임시(ephemeral) 포트에 바인딩되며, 그 포트는 udp-addresses를 호출해 알 수 있어요.
hostname-string이 #f이면 소켓은 port-no의 리스닝 머신의 모든 IP 주소로의 연결을 받아들여요. 그렇지 않으면 소켓은 주어진 이름과 연관된 IP 주소에서만 연결을 받아들여요. 예를 들어 hostname-string으로 "127.0.0.1"을 제공하면 일반적으로 로컬 머신에서 "127.0.0.1"로의 연결만 받아들이는 리스너가 만들어져요.
소켓은 로컬 주소와 포트에 바인딩되기 전까지 데이터그램을 받을 수 없어요. 소켓이 udp-send, udp-send-to 등 보내기 프로시저와 함께 사용되기 전에 바인딩되지 않았다면, 보내기 프로시저는 소켓을 임의의 로컬 포트에 바인딩해요. 마찬가지로 udp-send-evt 또는 udp-send-to-evt의 이벤트가 동기화(Events 문서 참고)를 위해 선택되면 소켓이 바인딩되고, 이벤트가 선택되지 않으면 소켓은 바인딩될 수도 있고 아닐 수도 있어요.
바인딩된 소켓의 바인딩은 변경될 수 없어요. 단 한 가지 예외가 있어요: 일부 시스템에서, 소켓이 보낼 때 자동으로 바인딩되었고, udp-connect!로 소켓이 연결 해제되었으며, 나중에 그 소켓이 다시 보내기에 사용된다면, 나중의 보내기가 소켓의 자동 바인딩을 변경할 수 있어요.
udp-socket이 이미 바인딩되었거나 닫혀 있으면 exn:fail:network 예외가 일어나요.
reuse? 인자가 참이면 udp-bind!는 바인딩 전에 SO_REUSEADDR 소켓 옵션을 설정하며, 이는 UDP 멀티캐스트를 사용할 때 단일 머신의 여러 프로세스가 UDP 포트에 대한 접근을 공유할 수 있게 해줘요.
(udp-connect! udp-socket hostname-string port-no) → void?
udp-socket : udp?
hostname-string : (or/c string? #f)
port-no : (or/c port-number? #f)
procedure
hostname-string이 문자열이고 port-no가 정확한 정수이면 소켓을 지정된 원격 주소와 포트에 연결해요.
hostname-string이 #f이면 port-no도 #f여야 하며, 포트는 (연결되어 있다면) 연결이 해제돼요. hostname-string이나 port-no 중 하나가 #f이고 다른 하나는 #f가 아니면 exn:fail:contract 예외가 일어나요.
연결된 소켓은 udp-send(udp-send-to 아님)와 함께 사용할 수 있으며, 연결된 주소와 포트에서만 데이터그램을 받아들여요. 데이터그램을 받는 데 소켓이 연결될 필요는 없어요. 소켓은 몇 번이든 연결, 재연결, 연결 해제될 수 있어요.
udp-socket이 닫혀 있으면 exn:fail:network 예외가 일어나요.
(udp-send-to udp-socket hostname port-no bstr [start-pos end-pos]) → void?
udp-socket : udp?
hostname : string?
port-no : port-number?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
(subbytes bytes start-pos end-pos)를 연결되지 않은 udp-socket에서 port-no 포트의 원격 머신 hostname-address에 있는 소켓으로 데이터그램으로 보내요. udp-socket은 바인딩되거나 연결될 필요가 없으며, 바인딩되지 않았다면 udp-send-to는 그것을 임의의 로컬 포트에 바인딩해요. 소켓의 나가는 데이터그램 큐가 보내기를 지원하기에 너무 꽉 차면, udp-send-to는 데이터그램이 큐에 들어갈 수 있을 때까지 블록돼요.
start-pos가 bstr의 길이보다 크거나, end-pos가 start-pos보다 작거나 bstr의 길이보다 크면 exn:fail:contract 예외가 일어나요.
udp-socket이 닫혀 있거나 연결되어 있으면 exn:fail:network 예외가 일어나요.
(udp-send udp-socket bstr [start-pos end-pos]) → void?
udp-socket : udp?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-send-to와 같지만, udp-socket이 연결되어 있어야 하며 데이터그램이 연결 대상으로 간다는 점이 달라요. udp-socket이 닫혀 있거나 연결되어 있지 않으면 exn:fail:network 예외가 일어나요.
(udp-send-to* udp-socket hostname port-no bstr [start-pos end-pos]) → boolean?
udp-socket : udp?
hostname : string?
port-no : port-number?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-send-to와 같지만 절대 블록되지 않아요. 소켓의 나가는 큐가 보내기를 지원하기에 너무 꽉 차면 #f가 돌려지고, 그렇지 않으면 데이터그램이 큐에 들어가고 결과는 #t예요.
(udp-send* udp-socket bstr [start-pos end-pos]) → boolean?
udp-socket : udp?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-send와 같지만, (udp-send-to처럼) 절대 블록되지 않고 #f 또는 #t를 돌려줘요.
(udp-send-to/enable-break udp-socket hostname port-no bstr [start-pos end-pos]) → void?
udp-socket : udp?
hostname : string?
port-no : port-number?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-send-to와 같지만, 데이터그램을 보내는 동안 브레이크(break, Breaks 문서 참고)가 활성화돼요. udp-send-to/enable-break가 호출될 때 브레이킹이 비활성화되어 있으면, 데이터그램이 보내지거나 exn:break 예외가 일어나는데 둘 다는 아니에요.
(udp-send/enable-break udp-socket bstr [start-pos end-pos]) → void?
udp-socket : udp?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-send와 같지만, 브레이크가 udp-send-to/enable-break처럼 활성화돼요.
(udp-receive! udp-socket bstr [start-pos end-pos])
→ exact-nonnegative-integer?
string?
port-number?
udp-socket : udp?
bstr : (and/c bytes? (not immutable?))
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-socket의 다음 수신 데이터그램의 end-pos-start-pos 바이트까지 bstr에 받아들이고, bstr 내의 start-pos 위치부터 데이터그램 바이트를 써요. udp-socket은 로컬 주소와 포트에 바인딩되어야 해요 (연결될 필요는 없어요). 수신 데이터그램이 즉시 없으면 udp-receive!는 하나가 생길 때까지 블록돼요.
세 개의 값이 돌려져요: 받은 바이트 수(0과 end-pos-start-pos 사이), 데이터그램의 소스 주소를 나타내는 호스트네임 문자열, 데이터그램의 소스 포트를 나타내는 정수. 받은 데이터그램이 end-pos-start-pos 바이트보다 길면 나머지는 버려져요.
start-pos가 bstr의 길이보다 크거나, end-pos가 start-pos보다 작거나 bstr의 길이보다 크면 exn:fail:contract 예외가 일어나요.
(udp-receive!* udp-socket bstr [start-pos end-pos])
→ (or/c exact-nonnegative-integer? #f)
(or/c string? #f)
(or/c port-number? #f)
udp-socket : udp?
bstr : (and/c bytes? (not immutable?))
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-receive!와 같지만 절대 블록되지 않아요. 데이터그램이 없으면 세 결과 값 모두 #f예요.
(udp-receive!/enable-break udp-socket bstr [start-pos end-pos])
→ exact-nonnegative-integer?
string?
port-number?
udp-socket : udp?
bstr : (and/c bytes? (not immutable?))
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
udp-receive!와 같지만, 데이터그램을 받는 동안 브레이크가 활성화돼요. udp-receive!/enable-break가 호출될 때 브레이킹이 비활성화되어 있으면, 데이터그램이 수신되거나 exn:break 예외가 일어나는데 둘 다는 아니에요.
(udp-set-receive-buffer-size! udp-socket size) → void?
udp-socket : udp?
size : exact-positive-integer?
procedure
udp-socket의 수신 버퍼 크기(SO_RCVBUF)를 설정해요. 더 큰 버퍼를 사용하면 주요 가비지 컬렉션 중을 포함해 연결의 느린 폴링 때문에 발생할 수 있는 패킷 손실을 최소화할 수 있어요.
size가 시스템이 허용하는 최대값보다 크면 exn:fail:network 예외가 일어나요.
base 패키지 7.1.0.11 버전에서 추가되었어요.
(udp-close udp-socket) → void?
udp-socket : udp?
procedure
udp-socket을 닫고, 받지 않은 데이터그램을 버려요. 소켓이 이미 닫혀 있으면 exn:fail:network 예외가 일어나요.
(udp? v) → boolean?
v : any/c
procedure
v가 udp-open-socket이 만든 소켓이면 #t, 그렇지 않으면 #f를 돌려줘요.
(udp-bound? udp-socket) → boolean?
udp-socket : udp?
procedure
udp-socket이 로컬 주소와 포트에 바인딩되어 있으면 #t, 그렇지 않으면 #f를 돌려줘요.
(udp-connected? udp-socket) → boolean?
udp-socket : udp?
procedure
udp-socket이 원격 주소와 포트에 연결되어 있으면 #t, 그렇지 않으면 #f를 돌려줘요.
(udp-send-ready-evt udp-socket) → evt?
udp-socket : udp?
procedure
udp-socket에 대한 udp-send-to가 블록될 때 블로킹 상태인 동기화 가능한 이벤트(Events 문서 참고)를 돌려줘요. 동기화 결과는 이벤트 자신이에요.
(udp-receive-ready-evt udp-socket) → evt?
udp-socket : udp?
procedure
udp-socket에 대한 udp-receive!가 블록될 때 블로킹 상태인 동기화 가능한 이벤트(Events 문서 참고)를 돌려줘요. 동기화 결과는 이벤트 자신이에요.
(udp-send-to-evt udp-socket hostname port-no bstr [start-pos end-pos]) → evt?
udp-socket : udp?
hostname : string?
port-no : port-number?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
동기화 가능한 이벤트를 돌려줘요. udp-socket에 대한 udp-send-to가 블록될 때 이벤트는 블로킹 상태예요. 그렇지 않으면, 동기화에서 이벤트가 선택되면 (udp-send-to udp-socket hostname-address port-no bstr start-pos end-pos)에서처럼 데이터가 보내지고 동기화 결과는 #<void>예요. (이벤트가 선택되지 않으면 바이트가 보내지지 않아요.)
(udp-send-evt udp-socket bstr [start-pos end-pos]) → evt?
udp-socket : udp?
bstr : bytes?
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
동기화 가능한 이벤트를 돌려줘요. udp-socket에 대한 udp-send가 블록되지 않을 때 이벤트는 동기화 준비가 돼요. 그렇지 않으면, 동기화에서 이벤트가 선택되면 (udp-send-to udp-socket bstr start-pos end-pos)에서처럼 데이터가 보내지고 동기화 결과는 #<void>예요. (이벤트가 선택되지 않으면 바이트가 보내지지 않아요.) udp-socket이 닫혀 있거나 연결되어 있지 않으면 동기화 시도 중에 exn:fail:network 예외가 일어나요.
(udp-receive!-evt udp-socket bstr [start-pos end-pos]) → evt?
udp-socket : udp?
bstr : (and/c bytes? (not immutable?))
start-pos : exact-nonnegative-integer? = 0
end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
동기화 가능한 이벤트를 돌려줘요. udp-socket에 대한 udp-receive가 블록되지 않을 때 이벤트는 동기화 준비가 돼요. 그렇지 않으면, 동기화에서 이벤트가 선택되면 (udp-receive! udp-socket bytes start-pos end-pos)에서처럼 데이터가 bstr에 수신되고 동기화 결과는 udp-receive!의 세 결과에 대응하는 세 값의 리스트예요. (이벤트가 선택되지 않으면 바이트가 수신되지 않고 bstr 내용이 수정되지 않아요.)
(udp-addresses udp-port [port-numbers?])
→ (or/c (values string? string?)
(values string? listen-port-number?
string? listen-port-number?))
udp-port : udp?
port-numbers? : any/c = #f
procedure
port-numbers?가 #f(기본값)이면 두 문자열을 돌려줘요. 첫 번째 문자열은 주어진 UDP 소켓의 연결에서 본 로컬 머신의 인터넷 주소예요. (대부분의 머신에서 그 답은 현재 머신의 유일한 인터넷 주소에 대응하지만, 머신이 여러 주소를 서비스할 때는 결과가 연결별로 달라져요.) 두 번째 문자열은 연결의 다른 쪽 끝의 인터넷 주소예요.
port-numbers?가 참이면 네 개의 결과가 돌려져요: 로컬 머신의 주소 문자열, 로컬 머신의 포트 번호에 대한 1과 65535 사이의 정확한 정수(소켓이 바인딩되지 않았으면 0), 원격 머신의 주소 문자열, 원격 머신의 포트 번호에 대한 1과 65535 사이의 정확한 정수(소켓이 연결되지 않았으면 0).
주어진 포트가 닫혀 있으면 exn:fail:network 예외가 일어나요.
(udp-set-ttl! udp-socket ttl) → void?
udp-socket : udp?
ttl : byte?
procedure
(udp-ttl udp-socket) → byte?
udp-socket : udp?
procedure
time-to-live 설정은 소켓의 IP_TTL 설정에 대응해요.
udp-socket의 현재 time-to-live 설정을 설정하거나 가져와요.
base 패키지 7.5.0.5 버전에서 추가되었어요.
(udp-multicast-join-group! udp-socket multicast-addr hostname) → void?
udp-socket : udp?
multicast-addr : string?
hostname : (or/c string? #f)
procedure
(udp-multicast-leave-group! udp-socket multicast-addr hostname) → void?
udp-socket : udp?
multicast-addr : string?
hostname : (or/c string? #f)
procedure
udp-socket을 명명된 멀티캐스트 그룹에 추가하거나 제거해요.
multicast-addr 인자는 유효한 IPv4 멀티캐스트 IP 주소여야 해요. 예를 들어 "224.0.0.251"은 mDNS 프로토콜에 적합한 주소예요. hostname 인자는 소켓이 멀티캐스트 데이터그램을 받는(보내는 게 아니라) 인터페이스를 선택해요. hostname이 #f 또는 "0.0.0.0"이면 커널이 인터페이스를 자동으로 선택해요.
그룹을 떠나려면 그룹에 가입할 때 사용한 것과 같은 multicast-addr와 hostname 인자가 필요해요.
(udp-multicast-interface udp-socket) → string?
udp-socket : udp?
procedure
(udp-multicast-set-interface! udp-socket hostname) → void?
udp-socket : udp?
hostname : (or/c string? #f)
procedure
udp-socket이 멀티캐스트 데이터그램을 보내는(받는 게 아니라) 데 사용하는 인터페이스를 가져오거나 설정해요. 결과나 hostname이 #f 또는 "0.0.0.0"이면 멀티캐스트 데이터그램이 보내질 때 커널이 인터페이스를 자동으로 선택해요.
(udp-multicast-set-loopback! udp-socket loopback?) → void?
udp-socket : udp?
loopback? : any/c
procedure
(udp-multicast-loopback? udp-socket) → boolean?
udp-socket : udp?
procedure
loopback 설정은 소켓의 IP_MULTICAST_LOOP 설정에 대응해요.
udp-socket이 자기 자신의 멀티캐스트 데이터그램을 받는지 설정하거나 확인해요: #t 결과 또는 loopback?에 대한 참 값은 자기 수신이 활성화되었음을, #f는 자기 수신이 비활성화되었음을 나타내요.
(udp-multicast-set-ttl! udp-socket ttl) → void?
udp-socket : udp?
ttl : byte?
procedure
(udp-multicast-ttl udp-socket) → byte?
udp-socket : udp?
procedure
time-to-live 설정은 소켓의 IP_MULTICAST_TTL 설정에 대응해요.
udp-socket의 현재 time-to-live 설정을 설정하거나 가져와요.
time-to-live 설정은 거의 항상 1이어야 하며, 이 숫자가 가능한 한 낮은 것이 중요해요. 사실 이 함수들은 거의 사용되어서는 안 돼요. 플랫폼의 IP 스택에 대한 문서를 참고하세요.