2016-07-27 3 views
4

에서 나는 다음과 같은 코드가있는 경우 :펄 소켓 : 증가 포트 사용

cannot create socket Address already in use 
: 내가 한 화면이를 시작하고 다른 화면에서 다른 하나를 시작하면

use IO::Socket::INET; 
use Sys::Hostname; 
use Socket; 


my($addr)=inet_ntoa((gethostbyname(hostname))[4]); 

my $port_to_use = 7777; 

my $socket = new IO::Socket::INET (
     LocalHost => $addr, 
     LocalPort => $port_to_use, 
     Proto => 'tcp', 
     Listen => 5, 
     Reuse => 1 
    ); 
die "cannot create socket $!\n" unless $socket; 
my $client_socket = $socket->accept(); 

, 오류가 발생합니다

죽어가는 대신 사용할 포트를 찾을 때까지 다른 포트 (1 씩 증가)를 사용하려고합니다.

나는 eval으로 die 라인을 변환 할 수 있지만이

제안을 잡을 수 메신저하려고했다?

답변

3

실제로 고장이 주어진 포트에 바인딩 할 수 있는지가 사용되는 포트에 기인하기 위해 확인하는 정돈 대안입니다. 또한 검사 할 포트 범위를 제한합니다. 코드 in the other answer을 사용하고 어떤 이유로 시스템에서 응용 프로그램이 포트에 바인딩하지 못하는 경우 무한 루프에 빠지게됩니다. 또한 기타 방식 등

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Carp qw(croak); 
use Errno qw(EADDRINUSE); 
use IO::Socket::INET; 
use Sys::Hostname qw(hostname); 
use Socket; 

# These can come from a config file or command line 
# See also https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic.2C_private_or_ephemeral_ports 
# https://unix.stackexchange.com/a/39784/2371 

my @port_range = (0xC000, 0xFFFF); 

my $addr = inet_ntoa((gethostbyname(hostname))[4]); 
my $socket; 

TRY_PORT: 
for my $port ($port_range[0] .. $port_range[1]) { 
    warn "Trying port $port\n"; 

    $socket = IO::Socket::INET->new(
     LocalHost => $addr, 
     LocalPort => $port, 
     Proto => 'tcp', 
     Listen => 7, 
     Reuse => 0, 
    ); 

    if ($socket) { 
     warn "Bound to port $port\n"; 
     last TRY_PORT; 
    } 

    if (EADDRINUSE != $!) { 
     croak "Cannot bind to port '$port': $!"; 
    } 
    warn "Port in use, trying the next one\n"; 
} 

$socket->accept 
    or croak "..."; 
# ... 
+1

고맙습니다. 고맙습니다. – ealeon

+0

감사합니다. 유용 할 것입니다. 감사합니다! 나는 다양한 오류 유형에 대한 자원을 찾지 못하고있다. (그들이'Errno'에 있다면 나는 아무것도 보지 못합니다.) 그것에 대한 참고 자료를 알고 있습니까? – zdim

+0

https://stackoverflow.com/q/172199/100754를 참조하십시오. –

4

사용 루프 :

여기
use IO::Socket::INET; 
use Sys::Hostname; 
use Socket; 

my($addr)=inet_ntoa((gethostbyname(hostname))[4]); 

my $port_to_use = 7776; 
my $fail =1; 
my $socket; 

while ($fail == 1){ 
    $port_to_use++; 
    $fail = 0; 
    warn $port_to_use; 
    $socket = IO::Socket::INET->new (
     LocalHost => $addr, 
     LocalPort => $port_to_use, 
     Proto => 'tcp', 
     Listen => 5, 
     Reuse => 0 
    ) or $fail =1; 
} 
warn $socket->accept(); 
+0

첫 화면 작품을 왼쪽하지만 두 번째 화면에서 메신저 오류가 정의되지 않은의 "동의"방법은 호출 할 수 없습니다 "점점되어 있어야합니다 포트에 바인딩 응용 프로그램을 일으킬 수 있습니다 perl_server.pl 행 39 "에서 값"socket-> accept() "; – ealeon

+0

하지만 $ socket이 정의되지 않은 경우 왜 "제외"될까요? – ealeon

+0

원본이 더 정확하다고 생각합니다. 하지만 어떤 이유로 두 번째 화면에 문제가 있습니다. 자신을 코딩하고 오류가 발생하는지 확인할 수 있습니까? – ealeon