in reply to two-way socket works once only?

Is it even possible to go from read, to write, to read, to write on the same socket?"

Yes, unless either end closes the socket. Reading and writting is completely independant. Do you have code to show us so we can help you debug? Don't forget to flush (or autoflush) commands and responses to make sure the other end gets it when you expect the other end to get it.

Replies are listed 'Best First'.
Re^2: two-way socket works once only?
by ikegami (Patriarch) on Nov 23, 2004 at 19:05 UTC
    Here's a example server and socket:

    server.pl

    use strict; use warnings; use IO::Socket (); my $listen_fh = IO::Socket->new( Domain => IO::Socket::AF_INET(), Proto => 'tcp', LocalAddr => '127.0.0.1', Listen => 1, ) or die("Unable to create listening socket: $!$/"); print('Listening on port ', $listen_fh->sockport(), '.', $/); my $client_fh = $listen_fh->accept() or die("Unable to accept a connection: $!$/"); print('Accepted a connection from ', $client_fh->peerhost(), ':', $cli +ent_fh->peerport(), '.', $/); while (<$client_fh>) { print $client_fh uc($_); } print('Connection closed by client or by error.', $/);

    client.pl

    use strict; use warnings; use IO::Socket (); my $peer_port = shift(@ARGV) or die("Specify the port on the command line.$/"); my $server_fh = IO::Socket->new( Domain => IO::Socket::AF_INET(), Proto => 'tcp', PeerAddr => '127.0.0.1', PeerPort => $peer_port, ) or die("Unable to connect to server: $!$/"); print('Connected to ', $server_fh->peerhost(), ':', $server_fh->peerpo +rt(), '.', $/); print('Type stuff to be uppercased by server. Blank line to exit.', $/ +); for (;;) { last if (!defined($_ = <STDIN>) || $_ eq $/); print $server_fh $_; last if (!defined($_ = <$server_fh>)); print; } print('Connection closed by server or by error or by request.', $/);
      I'm going over your code for clues that may help me. In the meantime, here is the code I am working on. Server.pl works fine as is, but if I try to put the code inside a while loop (I have tried both inside the socket open/close calls and outside) it quits working.

      edit: I changed my server.pl a bit based on what I saw in your example. This does not work. The while loop goes through the first iteration fine, and hangs up the second time through with a (error|warning) message of "Use of uninitialized value in substitution (s///) at /clocal/mptsgrp/user/mptsuser/scripts/guipartner.pl line 24, <GEN1> line 2."
      The print statements I included for debug show that $incoming matched /.+/ even after it was set to "" on the first iteration, but it did fail the $command[0] eq "check" test. The killer, though, is that the while loop stopped there. "Hi" was never printed a third time. :-(
      #!/usr/bin/perl use strict; use warnings; use IO::Socket; my $incoming; my $check; my @check; my @command; my $new_sock; my $sock = new IO::Socket::INET ( LocalPort => '8888', Proto => 'tcp', Listen => 1, Reuse => 1, ); die "Could not create socket: $!\n" unless $sock; $new_sock = $sock->accept(); while ($incoming = <$new_sock>){ print "hi"; if ($incoming =~ m/.+/){ print $incoming; @command = split / /,$incoming; $command[1] =~ s/\W+//g; $incoming = ""; if ($command[0] eq "check"){ $check = @check = `ps -ef |grep $command[1]`; print "$check\n@check\n"; if ($check >= 12) { print $new_sock "up"; } else { print $new_sock "down"; } }else{ print"did not work\n"; } } } close $sock;


      Likewise, the client works, so long as I don't duplicate the code to send a second request to the server.
      #!/usr/bin/perl use strict; use warnings; use IO::Socket; use Fcntl; my $input; my $sock; my $cs2; my $mqpcx; my $mpts; my $EOL = "\015\012"; my $BLANK = $EOL x 2; my $command; open OUT, "> testpage.html" or die "unable to write testpage"; ### OUT is temporary until I get cgi working. open FILE1, "< 1.html" or die; while (<FILE1>){print OUT} close FILE1; $sock = new IO::Socket::INET ( PeerAddr => '53.230.116.97', PeerPort => '8888', Proto => 'tcp', ); if ($sock){ print "Connection established\n"; $command = "check cs2" . $BLANK; print $sock $command; while ($cs2 = <$sock>){ last if ($cs2 =~ m/.+/); } if ($cs2 eq "up") { print OUT "<img src=\"./cs2up.gif\">\n"; $mpts++; print"so far, so good\n"; } elsif ($cs2 eq "down") { print OUT "<img src=\"./cs2down.gif\">\n"; } else { print "error getting data from other box"; } }else{ print OUT "<img src=\"./cs2down.gif\">\n"; print "no connection to other box"; } close($sock); close OUT; print "goodbye\n";

      --
      Believe nothing, no matter where you read it, or who said it - even if I have said it - unless it agrees with your own reason and your own common sense.
      (Buddha)

        Well, if I look at the server, it goes:

        • Get a bunch of text from the client.
        • Run ps, etc
        • Send response to client.
        • Close client.

        Shouldn't that be:

        • While the client is still connected,
          • Get a command from the client.
          • Run ps, etc
          • Send response to client.