UDP 서버 방송을 듣고 있습니다
-
03-07-2019 - |
문제
을 고려하면:
서버는 Windows XP에 있습니다
서버는 내부 네트워크 및 외부 네트워크에 연결되어 있습니다.
내부 네트워크의 컴퓨터는 포트 9722에서 UDP로 10.4.255.255로 방송됩니다.
나는 필요하다 :
방송을 듣고 메시지를 함수로 전달하십시오.
이것은 내가 사용하는 코드입니다.
my $sock;
do {
eval {
$sock = IO::Socket::INET->new(LocalPort => 9722, Proto => 'udp')
or die("Couldn't open the socket: $@");
1;
};
warn($@) and sleep(5) if($@);
} while ($@);
for(my $i = 0;$i < 20;$i++) {
my $string = 'a';
$sock->recv($string,1024);
print &parseInput($string);
}
& parseinput은 전달 된 원래 문자열을 반환합니다.
내 문제:
$ sock-> recv ()를 호출 한 후 $ string이 비어 있습니다. 다른 응용 프로그램을 사용하여 의심 할 여지없이 10.4.255.255에서 정보가 방송되는 것을 볼 수 있지만 액세스 할 수는 없습니다.
가능하다면 io :: socket :: inet을 사용하여 계속 사용하고 싶습니다.
편집 : Recv (..) 및 $!의 반환 값을 확인했습니다. recv (..)와 $의 반환 값은 없습니다! = '알 수없는 오류'.
편집 2 : 소켓을 사용하려고합니다. 이제 다음과 같이하십시오.
$proto = getprotobyname('udp');
socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) or die "socket: $!";
setsockopt(SOCKET, SOL_SOCKET, SO_BROADCAST, 1) or die "sockopt: $!";
bind(SOCKET, sockaddr_in(9722, inet_aton('192.168.0.103'))) or die "bind: $!";
recv(SOCKET, $msg, 128, 0) or die "recv: $!";
오류가 생성됩니다. RECV : 알 수없는 오류가 ...
해결책
나는 당신이 주요 문제를 발견했다고 생각합니다.
수신기는 모든 인터페이스 (inaddr_any) 또는 네트워크의 브로드 캐스트 주소 (모든 네트워크 하나 또는 지시 된 것)에 바인딩해야합니다.
다음은 방송 발신자와 수신자 모두에 대한 예제 코드입니다.
setsockopt를 사용할 때 조심하십시오! 마지막 인수를 포장해야합니다.
#!/usr/bin/perl -w
# broadcast sender script
use strict;
use diagnostics;
use Socket;
my $sock;
my $receiverPort = 9722;
my $senderPort = 9721;
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket: $!";
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!";
setsockopt($sock, SOL_SOCKET, SO_BROADCAST, pack("l", 1)) or die "sockopt: $!";
bind($sock, sockaddr_in($senderPort, inet_aton('192.168.2.103'))) || die "bind: $!";
while (1) {
my $datastring = `date`;
my $bytes = send($sock, $datastring, 0,
sockaddr_in($receiverPort, inet_aton('192.168.2.255')));
if (!defined($bytes)) {
print("$!\n");
} else {
print("sent $bytes bytes\n");
}
sleep(2);
}
#!/usr/bin/perl -w
# broadcast receiver script
use strict;
use diagnostics;
use Socket;
my $sock;
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket: $!";
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!";
bind($sock, sockaddr_in(9722, inet_aton('192.168.2.255'))) || die "bind: $!";
# just loop forever listening for packets
while (1) {
my $datastring = '';
my $hispaddr = recv($sock, $datastring, 64, 0); # blocking recv
if (!defined($hispaddr)) {
print("recv failed: $!\n");
next;
}
print "$datastring";
}
다른 팁
반환 값을 확인하십시오 $sock->recv
, 그리고 print "$!\n"
. 어떤 종류의 오류 메시지가 인쇄됩니까? $string
비워 지나요? 당신은해야 할 수도 있습니다 $sock->connect(...)
또는 $sock->bind(...)
전화하기 전에 $sock->recv()
.