2011-06-20 3 views
1

次のコードは(擬似的な)httpサーバーです。それは単にhttpリクエストを返信します。
予期せぬ調整は、ftp://localhost:8888/のようなブラウザからのftp要求で発生します。これにより、ブラウザは接続され、永遠に接続されたままになります。Perlソケットはftpリクエストで(擬似)httpサーバーを中断します!

何が起こっているのか分かりません!
この動作を制御し、ftp要求を無視するにはどうすればよいですか?

#!/usr/bin/perl 
use strict; 
use Socket; 
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 
use IO::Poll; 

local *S; 
socket  (S, PF_INET , SOCK_STREAM , getprotobyname('tcp')) || die "socket: $!\n"; 
setsockopt (S, SOL_SOCKET, SO_REUSEADDR, 1) || die "setsockopt: $!\n"; 
bind  (S, sockaddr_in(8888, INADDR_ANY)) || die "bind: $!\n"; 
listen  (S, 10) || die "listen: $!\n"; 
fcntl(S, F_SETFL, fcntl(S, F_GETFL, 0) | O_NONBLOCK) || die "fcntl: $!\n"; 

my $poll=IO::Poll->new; 
$poll->mask(*S => POLLIN|POLLOUT); 


while(1) { 
    $poll->poll(); 
    for my $reader ($poll->handles(POLLIN)) { 
     my $remote = accept (my $connection, $reader); 
     my $bytes= sysread $connection,my $header,1024; 

     if (defined $bytes) { 
      if ($bytes == 0 || (index $header,"\r\n\r\n") < 0) { 
       close $remote; 
       next; 
      } 
     } else { 
      close $connection; 
      next; 
     } 

     syswrite $connection,"HTTP/1.1 200 OK\r\n\r\n".$header; 
     close $connection; 
    } 
} 

答えて

4

HTTPとは異なり、FTPはサーバーがクライアントに挨拶を送信することから始まります。この場合、クライアントはFTPサーバーと通信していると考え、FTPクライアントがHTTPクライアントと通信していると考えているときにHTTPコマンドを送信するのを待っています。

解決方法は、sysreadを試行する前にクライアントソケット($connection)のタイムアウトを設定することです。

関連する問題