in reply to Re: sockets and such in Perl
in thread sockets and such in Perl

The one catch, as I alluded to in my respose to Frodo, is that there is the possibility of a "false" match (i.e. a match in two of the files, but not all three), hence even if the first two processes on the pipeline find a match, I can't guarantee it wil be repeated with the third process.

My problems up until this point have really centered around this one fact, returning control to a process earlier on the pipeline and repeating the cycle of: if(match)then pass on to next process... this is complicated by the fact that the Eclipse/EPIC debugger craps out on me when I try and step through the code of any one of these processes (with the other two running in the background) and I can't seem to get my STDOUT print statements to work reliably once I've opened a socket for writing.

Can anyone give me an example of how to use a single socket in a bidirectional manner?

For instance, if I set a socket up to receive:

my $s_socket = IO::Socket::INET-> new('LocalPort' => $S_PORT, 'Proto' => 'tcp', 'Listen' => 2) or die "Third: Can't create socket to Second($!)\n"; while (my $second = $s_socket->accept) {...}

but then later on need to send over that same socket:

while(<$second>) { if($_ eq $match) { print $s_socket "$match\n"; scalar <$s_socket>; last; } }

Am I doing this in the correct manner - what steps am I forgetting? In a nutshell the statement above (both sending and on the receiving process end) is what has been giving me the most headache.

Any help would be much appreciated!

Replies are listed 'Best First'.
Re^3: sockets and such in Perl
by nothingmuch (Priest) on Jul 03, 2005 at 19:27 UTC
    Think of it this way... Process 2 only prints out lines which it knows that both process 1 and process 2 have. This is then relayed to process 3. So process 3 has a list of lines, that have all been known to match at least in the other two processes, and a list of other lines. The moment it finds a line that equals - it's done - we know it's in all 3 lists.

    The pipelining structure basically filters anything that is definately not a match in the transition from 1 to 2. Then it filters out anything that is definately not a match between 2 and 3. The first thing that results is the answer.

    For an example of a bidirectional TCP/IP type thing, without the IO::Socket interface (but you should be able to cope), see perlipc.

    But I stress that bidirectionality is not necessary =)

    -nuffin
    zz zZ Z Z #!perl
      The problem here is that, since I have to assume that each file/list is infinite, I can never get the total number of matching lines in Process 1 and 2. In a way, this is why the files are alphabetized, because at the point I get a match in 1 and 2, I have to be able to tell (from a finite range of names) if 3 has any kind of match. Alphabetically I can look at the list and say, "well with the match I have in 2, if I get to a point in list 3 that is alphabetically after my match, then I can definitively say that the 3 list has no match"

      quick question - will the following work:

      my $socket = IO::Socket::INET->new( LocalPort => $PORT, Proto => 'tcp', Listen => 2) or die "Can't create socket on port $PORT to Second($!)\n"; while (<FILE>) { print $socket $_; if(my $second = $socket->accept()) { #if someone sends me something, do something with it #then go back to sending the rest of the file } }
      Can I do this?
        There's really no need to accumilate all input =)

        Let's go through three imaginary lists:

        bar baz foo gorch ... baz foo fuzzy gorch ... bar bar bar gorch ...
        process 1 gets the first line, and just prints that stream out.

        Process 2 gets the output of process one, and it's own input.

        So process 2 reads 'bar' coming from proc 1, and then reads a line from it's own input, and sees that it's 'baz'. Since 'baz' comes after 'bar', we know that we need to progress the first input, so we read another line from proc 1. We got 'baz'. So now we have 'baz' and 'baz'. We print that out, and continue. Then it reads 'foo' from process 1, and 'foo' from process two. That is also printed. Next come 'gorch' and 'fuzzy'. They aren't the same. since 'fuzzy' is alphabetically earlier than 'gorch', we read the next word from process 2's input. The next line is 'gorch'. Since 'gorch' eq 'gorch', we print that out too. And so on and so forth...

        This process goes on infinitely. As much as process 3 likes to read from it.

        process 3 does the same job, only the stream it sees is 'baz', 'foo', 'gorch' ..., that is, the list of matches from the previous runs.

        The way it works is the same - it reads a line from the output of process 2 - 'baz', and a line from it's own input - 'bar'. 'bar' comes before 'baz', so we read more from process 3's input. it's 'bar' two more times, so we just keep on skipping. The next thing we find is 'gorch'. Since 'gorch' comes later than 'baz', we read from process 2's output instead of process 3's input - 'foo'. 'foo' lt 'gorch', so we skip more - 'gorch'. 'gorch' eq 'gorch' - that's the first match. We can stop now.

        -nuffin
        zz zZ Z Z #!perl