2012-12-04 3 views
3

Perl에서 소켓 클라이언트를 만들려고합니다. 서버 측은 로컬 호스트에서 실행되는 C 프로그램입니다.Perl 소켓 해시 보내기

소켓을 통해 해시를 보내야합니다. 다음은 내가 사용하고있는 코드입니다.

sub applyGlobalConfig { 
    my ($globalConfig, $ignoreData) = @_; 

    my $socket = IO::Socket::INET->new(PeerAddr => $PEER_HOST, 
             PeerPort => $PEER_PORT, 
             Proto => "tcp", 
             Type  => SOCK_STREAM) 
      or die "Couldn't connect to $PEER_HOST:$PEER_PORT : [email protected]\n"; 

    my $reconfigResult; 

    print $socket "$113\n"; 

    close($socket); 

    unless ($reconfigResult) { 
     return 0; 
    } 

    return ERR_NULL; 
} 

지금, 나는이 가지고있는 문제는 $globalConfig는 해시 참조를 포함하며, 나는 소켓을 통해이를 보내려고합니다. 나는 알아낼 수 없다. 나는 덤블러에 대한 약간의 참고를 찾았지만 많이 이해할 수 없었다. 해시를 어떻게 보내나요?

답변

1

이 경우 Storable 모듈을 사용하고 싶습니다. 예 :

수신 측 :

use strict; 
use IO::Socket::INET; 
use Storable; 
use Data::Dumper; 

my $sock = IO::Socket::INET->new(Listen => 5, LocalAddr => 'host', 
           LocalPort => 9000, Proto  => 'tcp'); 
while(my $s = $sock->accept) { 
    my $struct = Storable::fd_retrieve($s); 
    print Dumper($struct); 
} 

보내기 측 :

use strict; 
use IO::Socket::INET; 
use Storable; 

my $sock = IO::Socket::INET->new(PeerAddr => 'host', PeerPort => 9000, 
       Type  => SOCK_STREAM, Proto  => 'tcp') || die "Fail: $!"; 
my $struct = { 
    a => 1, 
    b => [2,3,4] 
}; 
Storable::nstore_fd($struct, $sock); 

는 FreeBSD의를 AMD64하는 i386을 리눅스에서 보내 테스트.

또한 Data :: Dumper를 사용하여 해시에서 문자열을 만든 다음 네트워크를 통해 더티하고 버그가 많은 메서드를 보낼 수 있습니다.

UPD :

, 나는 공간으로 구분 된 문자열로 펄 측면의 해시 값을 변환하는 방법을 고민하고있다.

조인을 사용하려고 /지도 조합 :

아마
my $serialized = join("\n", map { "$_ ".$struct->{$_} } keys %$struct)."\n"; 

C 측의 null로 끝나는 문자열을 사용하는 것이 더 쉽습니다 :이 간단한 경우

my $keyvalue_count = scalar keys(%$struct); 
my $serialized = join("\0", map { "$_\0".$struct->{$_} } keys %$struct)."\0"; 

을 내가 선호 것 C에서 네이티브 이후로 마지막 변이체를 사용하십시오.

+1

수신자는 C로 작성되었지만 나중에 Perl로 검색 할 수 있도록 데이터를 저장할지 모릅니다. – ikegami

+0

@ikegami Opps 나는 이것을 잊지 않았다. 이 경우에는 C에서 해시 구현 이후로 더욱 복잡해지기 쉽지 않습니다. 아마도 ** Storable :: fd_retrieve **를 고수 할 것입니다. 또는 ikegami가 말한 것처럼'key = value \ n'와 같은 텍스트로 보냅니다. – PSIAlt

+0

, 서버는 C 프로그램입니다. argc와 argv를 담고있는 구조체로서 이것들을 받는다. 내가 생각한 한 가지 방법은 해시 값을 공백으로 구분 된 문자열로 변환하는 것이 었습니다. 그것을 보내기 전에. 하지만, 나는 펄 (perl) 측의 해시 값을 공간으로 구분 된 문자열로 변환하는 방법을 고민하고있다.어떤 도움을 호평합니다 –

6

소켓을 통해 데이터 구조를 보내려면 바이트 스트림으로 "직렬화"해야합니다. 그런 다음 수신 프로그램은이를 역 직렬화하여 데이터 구조를 재구성해야합니다. 수신 프로그램이 스트림을 특정 양식으로 예상하면 송신 프로그램은 예상 된 형식을 생성해야합니다.

양면을 작성하는 경우 JSON 또는 XML과 같은 상황에 맞는 직렬화 형식을 선택할 수 있으며 둘 중 하나는 Perl 해시를 나타낼 수 있습니다. 그러나 구체적인 상황에 대해 자세히 알지 못하면 답안으로 제공 할 수있는 모든 것입니다.