views:

399

answers:

4

Hi:

I am working on a c# application that spawn new Processes to run Perl programs:

I was wondering if there is a way to use socket interface to let perl program to talk to c# application. If using socket, the address has to be local host: 127.0.0.1? How to choose which port number to use?

also,

Since the C# application spawn a Process to run Perl program, is there a way to use inter-process communication in c# to achieve this task? I mean maybe the process that is running the perl can send a message to the c# appilication?

Thanks.

A: 

Your best option is a socket. You can choose any port that is not in use, and is above 1024. But you might want to review a list of common port assignments just to make sure you don't choose a conflict with a program you have in your environment.

-- Edit:

It seems that link advises port numbers above 49152. Wow, times change :)

Noon Silk
Typically, I let the OS assign a random, open port to the server process. Then I pass the port to the client as a command line argument.
daotoad
Can you tell me how to let OS assign a random port? IPendPoint require a port number. And How can I get the random port number assigned to my process. Thanks.
Well, my processes are written in Perl all around, but I use the IO::Socket::INET library and merely do not specify a port. I then request the port from the object. This amounts to using the `bind` sytem call with the port set to 0. I'm not sure how you access that from C#.
daotoad
MSDN shows that if you create an IPEndPoint object with the port number set to 0, you get automatic assignment: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind.aspx
daotoad
+3  A: 

You could try named pipes (System.IO.Pipes on the .NET side, Win32::Pipe on the Perl side).

nitzmahone
I'm rooting for the Named Pipes
Salamander2007
Thanks for the help.
+4  A: 

Use the IO::Socket::INET module.

You can connect to a port on localhost

$sock = IO::Socket::INET->new('127.0.0.1:2525');

or to another address

$sock = IO::Socket::INET->new("host.example.com:6789");

These examples assume the Perl program will be the client and you've written the server in C#. If it's the other way around, use the IO::Select module. Below is an example from its documentation:

use IO::Select;
use IO::Socket;

$lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080);
$sel = new IO::Select( $lsn );

while (@ready = $sel->can_read) {
    foreach $fh (@ready) {
        if ($fh == $lsn) {
            # Create a new socket
            $new = $lsn->accept;
            $sel->add($new);
        }
        else {
            # Process socket
            # Maybe we have finished with the socket
            $sel->remove($fh);
            $fh->close;
        }
    }
}

Using this code, you'd then connect from C# to port 8080 on the localhost.

The choice of port is mostly arbitrary. Both sides need to agree on the rendezvous port, and you want to avoid ports below 1024. Whether you connect to localhost or another address is determined by the address to which the server is bound. To bind to a network-accessible address, modify the above code to use

$lsn = new IO::Socket::INET(Listen => 1, LocalAddr => "host.example.com:8080");

The backlog of size 1 (the Listen parameter) is unusual. A typical size is the value of SOMAXCONN from sys/socket.h.

Greg Bacon
A: 

You can manage without sockets and pipes: in C# you redirect standard input and output for spawned process (example),and then you are to write perl script that receives data from STDIN and sends result to STDOUT.

n0rd
you are correct. But I am using the stdout of perl script for logging purpose. I can do string searching on stdout, it is just I am not comfortable with searching in string to find the result.Thanks.