سؤال

وبالنظر إلى أن:
خادم على تشغيل ويندوز إكس بي ActiveState بيرل
توصيل الخادم إلى الشبكة الداخلية وشبكة خارجية
كمبيوتر على شبكة الاتصال الداخلية هو البث في UDP إلى 10.4.255.255 على المنفذ 9722

وأنا بحاجة إلى:
الاستماع إلى البث وتمرير الرسائل إلى وظيفة

وهذا هو رمز أنا باستخدام:


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-> ريكف ()، $ سلسلة تصبح فارغة. استخدام تطبيق آخر أستطيع أن أرى أنه من دون شك هناك المعلومات التي يتم بثها عبر 10.4.255.255، ولكن لا أستطيع الوصول إليه.
إذا كان ذلك ممكنا، وأود أن يبقى باستخدام IO :: :: المقبس INET.

وتحرير: لقد راجعت قيمة الإرجاع ريكف (..) و$ !. لا يوجد قيمة الإرجاع من ريكف (..) و$! = 'خطأ غير معروف'.

وتحرير 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: $!";

و
فهو يولد الخطأ - ريكف: خطأ غير معروف في ...

هل كانت مفيدة؟

المحلول

وأعتقد أنني وجدت أنك المشكلة الرئيسية.

والمتلقي لديه لربط إما إلى أي واجهة (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().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top