저는 Raspbian에서 Elixir/Erlang 패키지를 사용하여 간단한 UDP 보내기/받기 애플리케이션을 구축하려고 합니다. 정보로 사용하고 있습니다이 튜토리얼.
인터페이스에서 지정한 브로드캐스트 IP 주소의 네트워크로 UDP 패킷을 보내려고 하면 eth0
"권한 거부" 메시지가 나타납니다.
Linux에서 네트워크로 UDP 메시지를 브로드캐스트하는 것이 실제로 허용되지 않습니까? 그렇다면 특정 패키지에 메시지 브로드캐스트 권한을 어떻게 부여합니까? IP 주소 127.0.0.1을 사용하여 테스트했는데 localhost
오류가 발생하지 않았습니다.
답변1
BSD 소켓 API를 사용하여 브로드캐스트를 보내려면 대상이 브로드캐스트 주소임을 선언해야 합니다. 이는 시스템 호출을 통해 수행됩니다.setsockopt(2)
.
이는 예시이므로 임의로 사용하지 마세요.지로왜냐하면:
- 나는 전혀 모른다지로
- 문제는 erlang과 관련이 없고 BSD 소켓 API와 관련이 있습니다.
설명하기 위해 IPv4를 사용하겠습니다.루프백주소.로컬 호스트127.0.0.1뿐만 아니라 현재 127.0.0.1/8이므로 127.0.0.0/8 네트워크 블록의 일부입니다. 이는 (적어도 현재 Linux에서는) 다음과 같이 브로드캐스트 의미론을 지원한다는 것을 의미합니다.
$ ip route get 127.255.255.255
broadcast 127.255.255.255 dev lo table local src 127.0.0.1 uid 1000
cache <local,brd>
그러니 편리한 방법으로 복사하세요.socat
명령은 애플리케이션과의 통신을 디버깅하기 위한 훌륭한 도구입니다.
$ echo test | socat udp4-datagram:127.255.255.255:5555 -
2021/07/04 08:40:06 socat[327412] E sendto(5, 0x55976a7a1000, 5, 0, AF=2 127.255.255.255:5555, 16): Permission denied
이를 위해서는 대상이 브로드캐스트임을 선언해야 합니다.
$ echo test | socat udp4-datagram:127.255.255.255:5555,broadcast -
$ echo $?
0
$ echo test | strace -e trace=socket,setsockopt,sendto -- socat udp4-datagram:127.255.255.255:5555,broadcast -
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) = 5
setsockopt(5, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
sendto(5, "test\n", 5, 0, {sa_family=AF_INET, sin_port=htons(5555), sin_addr=inet_addr("127.255.255.255")}, 16) = 5
+++ exited with 0 +++
지로setsockopt(2)
그 참고자료 중에는인트라넷기준 치수문서 참조: socket_setopt()
.
socket_setopt() = gen_sctp:option() | gen_tcp:option() | gen_udp:option()
setopts(Socket, Options) -> ok | {error, posix()} Types Socket = socket() Options = [socket_setopt()]
소켓에 대해 하나 이상의 옵션을 설정합니다.
{broadcast, Boolean} (UDP sockets)
브로드캐스트 전송 권한을 활성화/비활성화합니다.
에 추가하는 방법을 알아내야 합니다.지로암호.