Avatar billede Slettet bruger
19. juni 2007 - 07:28 Der er 5 kommentarer og
1 løsning

setsockopt invalid argument

Jeg ønsker at sætte en timeout på min socket, hvilket også virker på mine debian sarge servere. Jeg bruger denne kode:

setsockopt(CLIENT,SOL_SOCKET,SO_RCVTIMEO,pack('LL',15,0)) or die "setsock: $!";

Men på mine Fedora Core 6 + CentOS servere får jeg følgende fejl:

setsock: Invalid argument
Avatar billede Slettet bruger
20. juni 2007 - 19:10 #1
Jeg kom uden om problemet ved at bruge følgende:

local $SIG{ALRM} = sub {exit;};
alarm 15;

Dette virker dog kun da jeg bruger fork(), og kan tåle at miste child processer. Så skriv endelig hvis du finder et svar til det oprindelige spørgsmål.
Avatar billede twinsen Nybegynder
12. august 2007 - 21:11 #2
Problemet er - så vidt jeg forstår - at den option ligger lige på grænsen af, hvad OS'er implementerer af features for sockets. Derfor er det ikke sært, at den bare griner og ellers gør ingenting, når du skifter OS.

Du behøver dog ikke at bruge fork's, men kan bare sætte din socket til, at være non-blocking og så bruge select kald (ret nemt med IO::Select), til at se, om noget rykker på din socket. På den måde, kan du selv kode din timeout i stil med (total pseudo):

setNonBlocking($socket);
$start = time;
while($start + $timeout < time){
  $s = IO::Select->new($socket);
  if($s->can_read(0)){
    $bingo = 1;
    last;
  }

  sleep(1);
}

håber det hjælper!
Avatar billede Slettet bruger
13. august 2007 - 02:15 #3
Jeg bruger desværre ikke IO::Socket men blot "Socket". Har du en løsning til den? :)
Avatar billede twinsen Nybegynder
04. september 2007 - 22:30 #4
Jamen, IO::Socket nedarver jo fra IO::Handle, så efter du har oprettet objektet (IO::Socket) han du anvende dens globject som et filehandle til alle funktioner der behøver sådan et, fuldstændig uden, at perl lægger mærke til det.

f.eks. kan du:

    my $sock = IO::Socket::INET->new(Proto => 'tcp',
                                    Blocking => 0,
                                    Timeout => 25);

    my $iaddr = inet_aton($ip);
    my $paddr = sockaddr_in($port, $iaddr);
    my $ret = connect($sock, $paddr);

Derfor vil din øvrige kode sikkert være ligeglad med hvad du bruger? IO::Socket er bare pænere, hvis du spørger mig :)
Ellers tvinger du den bare med hård hånd:

$flags = '';
fcntl(HANDLE, F_GETFL, $flags)
    or die "Couldn't get flags for HANDLE : $!\n";
$flags |= O_NONBLOCK;
fcntl(HANDLE, F_SETFL, $flags)
    or die "Couldn't set flags for HANDLE: $!\n";

og bruger det almindelig select kald som beskrevet på perldoc.perl.org.
Avatar billede Slettet bruger
05. september 2007 - 11:38 #5
Jeg bruger hverken IO::Socket eller IO::Handle. Jeg bruger bare "Socket".
Avatar billede twinsen Nybegynder
11. september 2007 - 22:06 #6
Jæs, men fordi IO::Socket nedarver fra IO::Handle, kan du bruge det objekt alle steder hvor, du ellers bare ville bruge et filehandle. Derfor kan du udskifte dit socket(FH,osv, osv) kald med et nye IO::Socket objekt, og resten af din kode, der forventer et filehandle vil fungere. Du skal selvfølgelig rette FH til $obj eller noget, men det er også det.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester