jryan has asked for the wisdom of the Perl Monks concerning the following question:
I seem to have run into a platform discrepency between win32/*nix... yet strangely, the script in question works on win32, but not on *nix! Here is the situation: I Have a server, which may or may not be running on the local host. This server stores data. When the server is connected to, it recieves data. First, the header is chopped off and validated; if it is valid, the data is then examined. If the data is actually a send request, the stored data is sent back to the client; otherwise, the data is stored. This system worked great on win32, and also on darwin. However, when I tried debugging on *nix, my retrieve method broke. It was originally this:
sub retrieve { my ($self, $var) = @_; $var = $self->{vars}->{$var->{name}.$var->{ref}}; my $address = exists($$var->{address}) ? $$var->{address} : '127.0 +.0.1'; my $message = IO::Socket::INET->new ( Proto => 'tcp', PeerAddr => $address, PeerPort => $$var->{port}, ) or die ( $self->cleanup($!) ); $message->autoflush(1); my $port = $message->sockport; if ($$var->{debug}) { print "Connected to ", $$var->{ref}, " for retrieving:\n"; print "\tPeerhost: ", $message->peerhost, "\n"; print "\tPeerport: ", $message->peerport, "\n"; print "\tLocalhost: ", $message->sockhost, "\n"; print "\tLocalport: ", $message->sockport, "\n\n"; } my $header = crypt(crypt($$var->{ref},$$var->{ref}),$$var->{ref}); syswrite($message, $header."\bl\b", 3+length($header)); $message->close; $message = IO::Socket::INET->new ( Listen => SOMAXCONN, LocalPort => $port, Reuse => 1, LocalAddr => '127.0.0.1', ) or croak ( $self->cleanup($!) ); if ($$var->{debug}) { print "Listening for ", $$var->{ref}, ":\n"; print "\tLocalport: ", $message->sockport, "\n\n"; } while (my $connection = $message->accept) { if ($$var->{debug}) { print "Recieved a connection from ", $$var->{ref}, ":\n"; print "\tPeerhost: ", $connection->peerhost, "\n"; print "\tPeerport: ", $connection->peerport, "\n"; print "\tLocalhost: ", $connection->sockhost, "\n"; print "\tLocalport: ", $connection->sockport, "\n\n"; } my $sent = <$connection>; $connection->close if $connection; $sent = join('',map(chr,split(/\*/,$sent))); $sent = thaw($sent); $message->close; return $$sent; } $message->close if $message; }
However, this produced the error that the "address was already in use" (meaning the port was already in use) when I tried to open the listening socket; however, I had closed the socket a few lines earlier. Next, I remembered that sockets were bi-directional, so I tried to use the the same socket that I connected with to retrieve; however, this attempt caused the socket to hang:
Finally, my final attempt was similar to my first, with the exception that I opened my listening socket before the outgoing socket, and the port number the incoming was listening on sent along with the "send request" so that the server could connect to it. However, the server never got that far as opening the listening socket first caused the send to never occur:sub retrieve { my ($self, $var) = @_; $var = $self->{vars}->{$var->{name}.$var->{ref}}; my $address = exists($$var->{address}) ? $$var->{address} : '127.0 +.0.1'; my $message = IO::Socket::INET->new ( Proto => 'tcp', PeerAddr => $address, PeerPort => $$var->{port}, ) or die ( $self->cleanup($!) ); $message->autoflush(1); my $header = crypt(crypt($$var->{ref},$$var->{ref}),$$var->{ref}); syswrite($message, $header."\bl\b", 3+length($header)); my $sent = <$message>; $sent = join('',map(chr,split(/\*/,$sent))); $sent = thaw($sent); $message->close if $message->connected; return $$sent;
sub retrieve { my ($self, $var) = @_; $var = $self->{vars}->{$var->{name}.$var->{ref}}; my $address = exists($$var->{address}) ? $$var->{address} : '127.0 +.0.1'; my $incoming = IO::Socket::INET->new ( Listen => SOMAXCONN, LocalAddr => '127.0.0.1', Reuse => 1, ) or croak ( $self->cleanup($!) ); my $port = $incoming->sockport; $incoming->shutdown(1); my $message = IO::Socket::INET->new ( Proto => 'tcp', PeerAddr => $address, PeerPort => $$var->{port}, ) or die ( $self->cleanup($!) ); $message->autoflush(1); my $header = crypt(crypt($$var->{ref},$$var->{ref}),$$var->{ref}); syswrite($message, $header."\bl\b".$port, 3+length($header)+length +($port)); my $sent = <$connection>; $sent = join('',map(chr,split(/\*/,$sent))); $sent = thaw($sent); $incoming->close if $incoming->connected; $message->close if $message->connected; $connection->close if $connection->connected; return $$sent; }
I'm nearly at the end of my rope here; I've spent many hours debugging and tweaking and I'm still back at square one. I've tested on several different *nix platforms (solaris, red hat, caldera, debian) yet all produced the same error; why doesn't it work on *nix yet it works with both win32 and darwin?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re (tilly) 1: Socket Differences between Win32/Darwin and *nix.
by tilly (Archbishop) on Jan 10, 2002 at 16:44 UTC | |
by clintp (Curate) on Jan 10, 2002 at 19:30 UTC | |
by tye (Sage) on Jan 10, 2002 at 20:34 UTC |