You want to listen on a socket for something. How do you pick your port?



  • I have an app that when it runs, starts a socket listener thread. The idea is that when the same program runs again with an argument, it detects that it's not the only process running, opens a socket connection to localhost on that port and fires the argument down to the original instance before quitting.

    At the moment, when I chose a port, I just typed 5 numbers in at random (18293), but I can't help but feel there must be a better way than hard-coding a port number which might be used by something else.

    I used to use win32 messages, but they're not very cross platform (this is .net). Any ideas on how to do this better?



  • On Unix-like systems, there is a file called /etc/services where all known ports are listed. IIRC there is a similar file in Windows, too. Make sure your port number is not already listed in that file and add it to that file.



  • Well, any port below 1024 is "reserved" for well-known services.
    I'm guessing there is some inter-process communication system other than sockets.  What you're doing has been done before (Firefox does it I believe.)  There must be a common (simple) way of telling an existing processes "Oh, more stuff from command line."

    I don't know the .NET way, but look for inter process communication, or variants thereof



  • @danielpitts said:

    Well, any port below 1024 is "reserved" for well-known services.
    I'm guessing there is some inter-process communication system other than sockets.  What you're doing has been done before (Firefox does it I believe.)  There must be a common (simple) way of telling an existing processes "Oh, more stuff from command line."

    I don't know the .NET way, but look for inter process communication, or variants thereof


    Methods for IPC in windows are
    • named pipes
    • mailslots
    • Windows sockets
    Of these three, I've experience with mailslots (as a method for IPC), worked very well for me.

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/mailslots.asp



  • Originally, I was using win32 messages, which worked fine, but as I said, don't work on linux. Sockets work on both, but I'll do some investiation into named pipes.



  • Here's what the IANA has to say on the topic:


    If you expect your program to be widely distributed, then you should apply for a port number. Of course, since this is going to work on the loopback interface, it's pretty much irrelevant.



  • Can you not write the active port number into a simple file in your application directory, and all the instances can look up there for the port number



  • You allow the user to configure what port(s) he wants it to be.



  • you could make up some formula that returns the port number to use, e.g. (18000+dayofweek)



  • [quote user="morbogormo"]

    you could make up some formula that returns the port number to use, e.g. (18000+dayofweek)

    [/quote]

     

    great idea.  make the user forward 7 ports on his router. 



  • The best idea out of this lot is the "write-to-file-so-other-stuff-can-read-it" one. This socket is bound to localhost, so no firewall issues etc. Crucially, it's got to be able to work. If the program fires up and it can't bind a socket to the port number it has, it should pick another one. Repeat until it actually successfully begins listening. The problem is that the next instance of the program needs to know what that port is as well.

     I'll jsut write it to a file. Seems a bit of a hack though.
     



  • How about a unix socket? :P

    They behave just like internet sockets, but the socket is identified by a file on your filesystem, rather than a port number. You could put the socket file in either $TMPDIR, or in the user's home directory.


    http://www.ecst.csuchico.edu/~beej/guide/ipc/usock.html



  • That works on windows?



  • [quote user="growse"]That works on windows?[/quote]

    Sure. All you need is a little help from VMWare and a Linux Distro installed in it. 



  • [quote user="growse"]That works on windows?[/quote]

    No.. but does it need to? Use win32 messages on windows, unix sockets on unix.

    #ifdef __win32  /* if there is such a thing in .net */
    /* win32 code here */
    #else
    /* unix code here */
    #endif

    Personally, I'd just use normal internet sockets and put the port number in a configuration file.



  • [quote user="ammoQ"]On Unix-like systems, there is a file called /etc/services where all known ports are listed. IIRC there is a similar file in Windows, too. Make sure your port number is not already listed in that file and add it to that file.
    [/quote]

    The file is named services and for Windows NT 5x systems (2K,XP and Server 2003) this file is located at \windows\system32\drivers\etc



  • [quote user="tster"][quote user="morbogormo"]

    you could make up some formula that returns the port number to use, e.g. (18000+dayofweek)

    [/quote]

     

    great idea.  make the user forward 7 ports on his router. 

    [/quote]

    And it could potentionally mix up with 7 services instead of one :P Then you get users that call with problems like "hey - every monday - the program stops working, on tuesday it works fine though" :D

    Best way are indeed named pipes or unix sockets, but if you wanna use a tcp connection, just have it configurable in a file, or if you're a windows guy & like the registry - abuse that nasty thing.


Log in to reply