Pergunta

Tendo em conta que:
O servidor está no Windows XP rodando ActiveState Perl
O servidor está conectado a uma rede interna e uma rede externa
Um computador da rede interna está transmitindo em udp para 10.4.255.255 na porta 9722

Eu preciso:
ouvir a transmissão e passar as mensagens para uma função

Este é o código que estou usando:


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);
}

Observe que & parseInput retorna a string original foi passado.

Meu problema:
depois de chamar $ sock-> recv (), $ string torna-se vazia. Usando outro aplicativo eu posso ver que, sem dúvida, não há informação a ser transmitida através 10.4.255.255, mas eu não posso acessá-lo.
se possível, gostaria de permanecer usando IO :: Socket :: INET.

edit: Fui verificar o valor de retorno de recv (..) e US $ !. não há nenhum valor de retorno de recv (..) e $! = 'Erro desconhecido'.

Editar 2: Eu estou tentando uso soquete; agora e ter o seguinte:


$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: $!";


Ele gera o erro - recv: Erro desconhecido na ...

Foi útil?

Solução

Eu acredito que eu encontrei você está principal problema.

O receptor tem de se ligar tanto a qualquer interface (INADDR_ANY) ou para o endereço de broadcast da rede (ou a todas as redes de um ou aquela dirigida).

Aqui é exemplo de código, tanto para o remetente transmissão eo receptor.

Ao usar relógio setsockopt para fora! Você tem que embalar o último argumento.

#!/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";
}

Outras dicas

Verifique o valor de retorno de $sock->recv e print "$!\n". Que tipo de mensagem de erro não é possível imprimir quando $string fica vazia? Você pode ter que fazer $sock->connect(...) ou $sock->bind(...) antes de chamar $sock->recv().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top