scotchfx has asked for the wisdom of the Perl Monks concerning the following question:

UPDATE:

I am having issues being able to accept() a connection from a process on a socket that I established (and written to) at a previous point in my script... in an nutshell, I am trying to match input given to me by a First process, if I match this input in the Second process I send it to the Third process to see if I have yet another match.

Sending the data from First, to Second, to Third works fine.

My problem comes in being able to establish a connection "downstream" (Third, to Second, to First) using the same set of sockets that I originally used to send data "upstream". In short, I cannot seem to get my $socket->accept to pick up the response from Third to Second, and then from Second to First.

Below is a chunk of code that I've managed to isolate as the hangup in my project:

while (<$first>) { my $name = $_; chomp($name); #send acknowledgement message to First print "Received from [$f_host $f_port]: $name\n"; #print $f_socket "$.: $name\n"; #Sending info upstream to Third process #this part works fine if($name eq $match) { print "Second found match: $name\n"; print "Second sending \"$name\" to Third\n"; print $t_socket "$match\n"; } #after I send I am expecting a response #from Third process #I never get into this loop #it skips or accept() blocks indefinitely while(my $third = $t_socket->accept) { print "Second has accepted socket to Third...\n"; my $t_host = gethostbyaddr($third->peeraddr, AF_INET); my $t_port = $third->peerport; while (<$third>) { my $name = $_; chomp($name); print "Received from [$f_host $f_port]: $name\n"; if($name eq $match) { print "Received \"$name\" from Third\n"; last; } else { last; } } } }
Here is the sending part of the Third process:
if($name eq $match) { print "Third sending \"$name\" to Second\n"; print $socket "$name\n"; #close $second or die "Can't close ($!)\n"; last; }
This code seems to execute okay.

I'd be happy to include all three scripts if anyone is interested to look. I'm doing this for a class project (see http://www.perlmonks.org/?node_id=472004 for a better description).

#####PREVIOUS QUESTION#####

I have a quick IO::Socket question for those of you out there familiar w/ Perl IPC.

What is the difference between opening a socket with "LocalPort" as opposed to "PeerPort" (see code example below):

my $socket = IO::Socket::INET->new('LocalPort' => $PORT, 'Proto' => 'tcp', 'Listen' => 2) or die "Second: Can't create socket to First($!)\n"; #VERSUS my $socket = IO::Socket::INET-> new( 'PeerAddr' => "localhost", 'PeerPort' => $PORT, 'Proto' => 'tcp') or die "Second: Can't create socket to Third($!)\n";
In this instance, can each of these $socket be used to write or read from? Is the former only for listening, and the latter for sending or can I use both sockets equally?

Can I only do a $socket->accept on the former example, but not the latter?

This leads me to my next question... what is the reason behind doing the following:

while(my $handle = $socket->accept) { while(<$handle>) { #do something with $_ } }
Is this _only_ for receiving input from a socket via a handle, or can I use it to write to as well - some examples on the web use code that writes directly to the $handle ex) "print $first "hello"; ... is this correct form?

If I need to send a message across the socket, should I instead use print $socket "my message"; ? Should $handle = $socket->accept; only be used when listening on a socket?

Replies are listed 'Best First'.
Re: Bidirectional use of a Socket
by pg (Canon) on Jul 04, 2005 at 00:12 UTC

    The socket is bidirectional and not.

    This depends on the meaning of your question. If you are asking about whether you can both write to and read from the same socket, the answer is yes, the socket is bidirectional, you can write to and also read from the same socket.

    On the other hand, you also asked the question about the difference between LocalPort and PeerPort. In that sense, socket is not "bidirectional", as a socket can either act as a server or a client, but not both. If you want the socket to act as a server and listen for connection from client, you create it with LocalPort; if you want the socket to act as a client and initiates teh connection to a server, then you use PeerPort (in which case, a LocalPort on the local is picked for you).

      What if I initiate the conversation (send a message) then need to listen for a response. If I open a socket:
      my $t_socket = IO::Socket::INET->new( 'PeerAddr' => "localhost", 'PeerPort' => $T_PORT, 'Proto' => 'tcp') or die "Second: Can't create socket to Third($!)\n";
      Send some data..
      if($name eq $match) { print "Second found match: $name\n"; print "Second sending \"$name\" to Third\n"; print $t_socket "$match\n"; }
      Then listen for a response...
      while(my $third = $t_socket->accept) { print "Second has accepted socket to Third...\n"; my $t_host = gethostbyaddr($third->peeraddr, AF_INET); my $t_port = $third->peerport; while (<$third>) { my $name = $_; chomp($name); print "Received from [$f_host $f_port]: $name\n"; if($name eq $match) { print "Received \"$name\" from Third\n"; last; } else { last; } } }
      Do I need to do a $t_socket->accept if the connection has already been established?

      Can you tell what I am doing wrong in the above example (since it's not working)?

      Thanks!

        One obvious problem is that accept. You don't need to accept, as the connection (between client and server) has been created already, at the time when you call ->new().

        On the client side, the porgram above, you can use $t_socket for both write and read, to "listen for response", all what you need to do is <$t_socket>. Of course , for better control, you can always use select, which is something you want to learn next step.