2012-01-17 3 views
0

GPS 장치 (소켓 클라이언트가 프로그래밍 됨)에서 GPS 좌표를 보내는 등 소켓 서버와 통신하는 차량 추적 시스템에서 작업하고 있습니다. 소켓 서버는 데이터를 구문 분석합니다 추가 처리를 위해 get 메소드를 통해 http 웹 서비스로 전송됩니다. 소켓 서버 동작을 연구하기 위해 로컬로 50 명의 클라이언트를 시뮬레이트했습니다. 불행히도 모든 클라이언트가 동일/다른 시간에 해고 되었음에도 불구하고 파싱/데이터 가져 오기가 지연됩니다. 그러나 제 요구 사항은 선착순입니다. 그러나이 맥락에서 그렇게 보이지는 않습니다. 매개 변수를 처리 할 내용이 new IO::Socket::INET();에 필요합니까? 다음은 내 소켓 서버 포트를 듣고 것은 11050.perl 소켓 클라이언트/서버가 패킷을 대기열에 넣는다

#!/usr/bin/perl 
use IO::Socket::INET; 

$| = 1; 

my ($socket,$client_socket); 
my ($peeraddress,$peerport); 
my $LOGFILE="/home/nuthan/program/input.log"; 
open (LOG,">>$LOGFILE"); 
$socket = new IO::Socket::INET (LocalHost => '192.168.1.110', 
           LocalPort => '11050', Proto => 'tcp', 
           Listen => 500, Reuse => 1, 
           Blocking => 0, Timeout => 2) 
    or die "ERROR in Socket Creation : $!\n"; 
while(1) { 
    # waiting for new client connection. 

    $client_socket = $socket->accept(); 
    #print "SOCKET $client_socket SOCKET\n"; 
    if (! $client_socket){ 
     next; 
    } 

    # Received from Client : 
    #356823033046306##0#0000#AUT#1#V#07734.7000,E,1259.5355,N,000.00,288#211011#085017## 
    #EMI's code(15 numbers)#username#status#password#data type#data volume#base station information#longitude, E,latitude, N, speed, direction#date#time## 
    $client_socket->recv($data,1500); 
    print "Received from Client : $data\n"; 
    #print LOG "Received from Client : $data\n"; 
    my ($blah,$EMI,$username,$status,$password,$data_type,$data_volume, 
     $base_station_info,$dir,$date,$time,$blah1)=split(/\#/,$data); 
    new_do_get($EMI,$dir,$date,$time); 
} 


sub new_do_get(){ 
    print "In new_do_get\n"; 
    my ($EMI,$dir,$date,$time) = @_; 
    my ($longitude,$e,$latitude,$n,$speed,$direction)=split(/,/,$dir); 
    my $url = "http://192.168.1.110:8080/prototype/socket/location.php?" 
     . "ln=$longitude&lt=$latitude&imei=$EMI&d=$date&o=0&v=$speed&t=$time"; 
    # print "$url\n"; 
    use LWP::Simple; 
    my $content = get $url; 
    die "Couldn't get $url" unless defined $content; 
} 

$socket->close(); 
close LOG; 
+0

주장하는 효과가 너무 많습니다. HTTP 요청 부분을 꺼내서 PHP 리스너와 네트워크 사이에서 독립적으로 수행하십시오. 타임 스탬프가있는 줄 단위 기록을 사용하십시오. - 50 클라이언트 시뮬레이션이 GPS 장치를 가짜로 추측 할 때 맞습니까? 그렇다면 해당 코드도 게시하십시오. – daxim

+3

한 클라이언트가 아무 것도 보내지 않고 소켓을 열어 놓고 앉아서 서버를 기다리고 다른 모든 클라이언트를 무시할 때까지 기다리는 것을 결정합니까? 각 클라이언트마다 포크 오프하거나'select'를 사용해야합니다. 후자를하는 대신 [POE'] (http://p3rl.org/POE)를 고려하십시오. – derobert

+0

thnx @derobert 오랫동안 기다리고 있다는 것을 깨달았습니다. 주변을 둘러 본 후, 그런 엄청난 양의 고객들과 함께 알게되었습니다. 멀티 스레딩 펄 소켓이 문제를 해결할 수 있습니다. 아래에 해당 코드를 게시했습니다. 자, 어디서 읽을/데이터를 받을지 잘 모르겠습니다. – nuthan

답변

0

멀티 스레딩 둘러보고 후 소켓 서버

을, 클라이언트와 같은 엄청난 양으로, 실현 는 멀티 스레딩 펄 소켓하면 문제를 충분 . 희망이 사람을 도울 수 있습니다. a link!

#!/usr/bin/perl -Tw 
use strict; 
BEGIN { $ENV{PATH} = '/usr/ucb:/bin' } 
use Socket; 
use Carp; 
my $EOL = "\015\012"; 

sub spawn; # forward declaration 
sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } 

my $port = shift || 11051; 
my $proto = getprotobyname('tcp'); 

($port) = $port =~ /^(\d+)$/      or die "invalid port"; 

socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; 
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 
       pack("l", 1)) || die "setsockopt: $!"; 
bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!"; 
listen(Server,SOMAXCONN)    || die "listen: $!"; 

logmsg "server started on port $port"; 

my $waitedpid = 0; 
my $paddr; 

use POSIX ":sys_wait_h"; 
sub REAPER { 
my $child; 
    while (($waitedpid = waitpid(-1,WNOHANG)) > 0) { 
    logmsg "reaped $waitedpid" . ($? ? " with exit $?" : ''); 
} 
$SIG{CHLD} = \&REAPER; # loathe sysV 
} 

$SIG{CHLD} = \&REAPER; 

for ($waitedpid = 0; 
    ($paddr = accept(Client,Server)) || $waitedpid; 
    $waitedpid = 0, close Client) 
{ 
read(Client, $buffer, 1000); 
next if $waitedpid and not $paddr; 
my($port,$iaddr) = sockaddr_in($paddr); 
my $name = gethostbyaddr($iaddr,AF_INET); 

logmsg "connection from $name [", 
    inet_ntoa($iaddr), "] 
$buffer 
#your data in $buffer 
    at port $port"; 

spawn sub { 
    $|=1; 
    print "Hello there, $name, it's now ", scalar localtime, $EOL; 
     or confess "can't exec fortune: $!"; 
}; 

} 

sub spawn { 
my $coderef = shift; 

unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { 
    confess "usage: spawn CODEREF"; 
} 

my $pid; 
if (!defined($pid = fork)) { 
    logmsg "cannot fork: $!"; 
    return; 
} elsif ($pid) { 
    logmsg "begat $pid"; 
    return; # I'm the parent 
} 
# else I'm the child -- go spawn 

open(STDIN, "<&Client") || die "can't dup client to stdin"; 
open(STDOUT, ">&Client") || die "can't dup client to stdout"; 
## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr"; 
exit &$coderef(); 
} 
관련 문제