[omniORB] Running more than one server on the same machine...

Sai-Lai Lo S.Lo@orl.co.uk
27 Jul 1998 10:40:40 +0100


Tom Haggie <THaggie@img.seagatesoftware.com> writes:

> Hi
> Is it possible to programmatically find a suitable port number to run
> our server on, we want to have more than one copy of the server running
> at the same time and so would like to have a different BOA port for each
> which is within a certain range specified range. 
> 
> I've tried creating a socket and then binding it to the port in question
> but this doesn't give an error as the socket within the ORB has the flag
> SO_REUSEADDR set on it.
> 

The ORB set the flag SO_REUSEADDR only when it is given a port number to
bind to.

One possible solution is to let the ORB picks a port but tells it to try
within a certain specified range. The following is a patch to do so.
Try it out and tell me what you think.

Sai-Lai

----------------------------------------------------

src/lib/omniORB2/tcpSocketMTfactory.cc:

tcpSocketIncomingRope::tcpSocketIncomingRope(tcpSocketMTincomingFactory* f,
					     unsigned int maxStrands,
					     tcpSocketEndpoint *e,
					     CORBA::Boolean export)
  : Rope(f->anchor(),maxStrands,1), pd_export(export), 
    pd_shutdown(NO_THREAD), rendezvouser(0)
{
  struct sockaddr_in myaddr;

  // For the moment, we do not impose a restriction on the maximum
  // no. of strands that can be accepted. In other words, <maxStrands> is 
  // ignored.

  if ((pd_rendezvous = socket(INETSOCKET,SOCK_STREAM,0)) == RC_INVALID_SOCKET) {
    throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
  }
  myaddr.sin_family = INETSOCKET;
  myaddr.sin_addr.s_addr = INADDR_ANY;
  myaddr.sin_port = htons(e->port());
  
  if (e->port()) {
    int valtrue = 1;
    if (setsockopt(pd_rendezvous,SOL_SOCKET,
		   SO_REUSEADDR,(char*)&valtrue,sizeof(int)) 
                         == RC_SOCKET_ERROR ||
	bind(pd_rendezvous,(struct sockaddr *)&myaddr,
	   sizeof(struct sockaddr_in)) == RC_SOCKET_ERROR)
      {
	CLOSESOCKET(pd_rendezvous);
	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
      }
  }
  else {
    // XXX
    //  To do this properly, portRangeBegin and portRangeEnd should be
    //  variables in the omniORB namespace and set either by a parameter
    //  in omniORB.cfg, NT registry or -BOAxxxx options.
    //  If portRangeBegin = portRangeEnd = 0, the ORB let the OS picks any
    //  available port.
    CORBA::UShort portRangeBegin = 7000;
    CORBA::UShort portRangeEnd   = 8000;

    CORBA::UShort scanport = portRangeBegin;
    while (scanport <= portRangeEnd) {
       myaddr.sin_port = htons(scanport);
       if (bind(pd_rendezvous,(struct sockaddr *)&myaddr,
     	        sizeof(struct sockaddr_in)) != RC_SOCKET_ERROR) {
         break;
       }
       scanport++;
    }
    if (scanport > portRangeEnd) {
	CLOSESOCKET(pd_rendezvous);
	throw CORBA::COMM_FAILURE(errno,CORBA::COMPLETED_NO);
    }
  }
       
  // Make it a passive socket


-- 
Dr. Sai-Lai Lo                          |       Research Scientist
                                        |
E-mail:         S.Lo@orl.co.uk          |       Olivetti & Oracle Research Lab
                                        |       24a Trumpington Street
Tel:            +44 223 343000          |       Cambridge CB2 1QA
Fax:            +44 223 313542          |       ENGLAND