PLearn 0.1
Public Member Functions | Static Protected Attributes
PLearn::ServerCommand Class Reference

#include <ServerCommand.h>

Inheritance diagram for PLearn::ServerCommand:
Inheritance graph
[legend]
Collaboration diagram for PLearn::ServerCommand:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ServerCommand ()
virtual void run (const std::vector< std::string > &args)
 The actual implementation of the 'ServerCommand' command.

Static Protected Attributes

static PLearnCommandRegistry reg_
 This allows to register the 'ServerCommand' command in the command registry.

Detailed Description

Definition at line 52 of file ServerCommand.h.


Constructor & Destructor Documentation

PLearn::ServerCommand::ServerCommand ( )

Definition at line 71 of file ServerCommand.cc.

                            :
    PLearnCommand("server",

                  "Launches plearn in computation server mode",

                  "server\n"
                  "  Launches plearn in stdin/stdout server mode, \n"
                  "  listening for commands on standard in \n"
                  "  and outputing results on standard out. \n"
                  " \n"
                  "server <tcp_port> [<outfile>] [-singleuse]\n"
                  "  Launches plearn in TCP server mode \n"
                  "  Will then print a line to outfile or to stdout (if no outfile is specified) of the form: \n"
                  "    PLEARN_SERVER_TCP hostname port pid\n"
                  "  Will then wait for a connection on the given TCP port. \n"
                  "  All i/o for commands are then done through that connection. \n"
                  "  If you specify -singleuse, then the server will exit when the conneciton \n"
                  "  with its first client is closed or lost."
        )
{}

Member Function Documentation

void PLearn::ServerCommand::run ( const std::vector< std::string > &  args) [virtual]

The actual implementation of the 'ServerCommand' command.

***///***

***///***

Implements PLearn::PLearnCommand.

Definition at line 93 of file ServerCommand.cc.

References PLearn::endl(), PLearn::PStream::flush(), PLearn::get_pio(), PLearn::getPrErrorString(), NORMAL_LOG, PLearn::openFile(), PLearn::perr, PLearn::PStream::plearn_ascii, PLERROR, PLearn::pout, PLearn::PStream::raw_ascii, PLearn::PLearnServer::run(), PLearn::PStream::setMode(), PLearn::toint(), and PLearn::tostring().

{
    if(args.size()>0) // Start TCP server on given port
    {
        PRStatus st;
        char buf[256];
        int port = toint(args[0]);

        bool singleuse=false;
        string outfile;
        if(args.size()>1)
        {
            if(args[1]=="-singleuse")
                singleuse = true;
            else
                outfile = args[1];
            if(args.size()>2 && args[2]=="-singleuse")
                singleuse = true;
        }

        PRFileDesc* sock = PR_NewTCPSocket();
        if (!sock)
            PLERROR("Servercommand: socket creation failed! (Maybe you ran out of file descriptors?)");
        PRNetAddr server_address;
        PR_InitializeNetAddr(PR_IpAddrAny, port, &server_address);
        if (PR_Bind(sock, &server_address) != PR_SUCCESS)
            PLERROR("ServerCommand: could not bind to port %d!", port);

        // Allow reuse of the socket immediately after the server shuts down
        PRSocketOptionData socket_option_data;
        socket_option_data.option = PR_SockOpt_Reuseaddr;
        socket_option_data.value.reuse_addr = PR_TRUE;
        PR_SetSocketOption(sock, &socket_option_data);

        string myhostname = "UNKNOWN_HOSTNAME";
        string mypid = "UNKNOWN_PID";      
#ifndef WIN32
        mypid = tostring(getpid());
        if(gethostname(buf, sizeof(buf))==0)
            myhostname = buf;
#endif

        PRNetAddr assigned_addr;
        PR_InitializeNetAddr(PR_IpAddrAny, PR_htons(0), &assigned_addr);
        st= PR_GetSockName(sock, &assigned_addr);
        if(port==0 && st==PR_SUCCESS)
            port= PR_ntohs(assigned_addr.inet.port);
        
        if(outfile.size()>0)
        {
            string tmpoutfile =outfile+".tmp";
            PStream out = openFile(tmpoutfile, PStream::raw_ascii, "w");
            out << "PLEARN_SERVER_TCP " << myhostname << " " << port << " " << mypid << endl;            
            out = 0; // close it
            PR_Rename(tmpoutfile.c_str(), outfile.c_str());
        }
        else
            pout << "PLEARN_SERVER_TCP " << myhostname << " " << port << " " << mypid << endl;

        NORMAL_LOG << "PLEARN_SERVER STARTING IN TCP MODE ON "  << myhostname << ", PORT " << port << ", PID " << mypid << endl;
        NORMAL_LOG << "singleuse = " << singleuse << endl;

        bool running = true;
        do  {
            NORMAL_LOG << "\nPLEARN_SERVER WAITING FOR CONNECTION"  << endl;
            
            pout << " JBL " << endl;

            st = PR_Listen(sock,0);
            if(st!=PR_SUCCESS)
                PLERROR("serverCommand: listen on socket failed");
            PRNetAddr addr;
            PRFileDesc* fd = PR_Accept(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
            if(fd==0)
                PLERROR("ServerCommand: accept returned 0, error code is: %d : %s",
                        PR_GetError(), getPrErrorString().c_str());
            st = PR_NetAddrToString(&addr, buf, sizeof(buf));
            NORMAL_LOG << "PLEARN_SERVER CONNECTION_FROM "  << buf << endl;
            PStream io(new PrPStreamBuf(fd,fd,true,true));

            PLearnServer server(io);
            running = server.run();
            io.flush();
            if (PR_Close(fd) != PR_SUCCESS)
                PLERROR("ServerCommand: couldn't close client socket from %s!", buf);

        } while(running && !singleuse);

        NORMAL_LOG << "PLEARN_SERVER CLOSING SOCKET" << endl;
        if (PR_Shutdown(sock, PR_SHUTDOWN_BOTH) != PR_SUCCESS)
            PLERROR("ServerCommand: couldn't shutdown socket %d!", port);
        if (PR_Close(sock) != PR_SUCCESS)
            PLERROR("ServerCommand: couldn't close port %d!", port);
    }
    else // Start stdin/stdout server
    {
        perr << "Type !? to get some help." << endl;
        // PStream io(&std::cin, &std::cout);
        // PStream io(new StdPStreamBuf(&std::cin,&std::cout));
        // PStream io(new FdPStreamBuf(0,1));
        PStream io = get_pio();
        io.setMode(PStream::plearn_ascii);
        PLearnServer server(io);
        server.run();
    }
}

Here is the call graph for this function:


Member Data Documentation

This allows to register the 'ServerCommand' command in the command registry.

Definition at line 59 of file ServerCommand.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines