PLearn 0.1
IPopen.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PLearn (A C++ Machine Learning Library)
00004 // Copyright (C) 2002 Frederic Morin
00005 // 
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 // 
00009 //  1. Redistributions of source code must retain the above copyright
00010 //     notice, this list of conditions and the following disclaimer.
00011 // 
00012 //  2. Redistributions in binary form must reproduce the above copyright
00013 //     notice, this list of conditions and the following disclaimer in the
00014 //     documentation and/or other materials provided with the distribution.
00015 // 
00016 //  3. The name of the authors may not be used to endorse or promote
00017 //     products derived from this software without specific prior written
00018 //     permission.
00019 // 
00020 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00021 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00023 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00025 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 // 
00031 // This file is part of the PLearn library. For more information on the PLearn
00032 // library, go to the PLearn Web site at www.plearn.org
00033  
00034 
00035 /* *******************************************************      
00036  * $Id: IPopen.cc 4048 2005-09-07 15:26:54Z plearner $
00037  * This file is part of the PLearn library.
00038  ******************************************************* */
00039 
00040 #include <sys/types.h>
00041 #if !defined(_MSC_VER) && !defined(_MINGW_) && !(defined WIN32)
00042 #include <sys/wait.h>
00043 #endif
00044 #include <plearn/base/stringutils.h>
00045 #include "IPopen.h"
00046 
00047 namespace PLearn {
00048 using namespace std;
00049 
00050 #ifndef _MINGW_
00051 // Default values for static (state) variables
00052 int IPServer::ip_port = 15000;
00053 int IPServer::max_connections = 100;
00054 
00055 void IPopen::launch(IPServer &server, const string& command) {
00056     if (verbose)
00057         cout << "IPopen launches:" << endl << command << endl;
00058 
00059     if (fork() == 0) {
00060         // Child process
00061         system(command.c_str());
00062         exit(1);
00063     }
00064     establish_communication(server);
00065 }
00066 
00067 IPopen::~IPopen() {
00068     //pipe.close(); // Not strictly necessary
00069     shutdown(socket_fd, 2);
00070     close(socket_fd);
00071 }
00072 
00073 // Wait for client to connect with server
00074 void
00075 IPopen::establish_communication(IPServer &server)
00076 {
00077     int addr_len = sizeof(struct sockaddr_in);
00078         
00079     // Wait for some client to connect
00080     socket_fd = accept(server.get_socket_fd(),
00081                        (struct sockaddr *)server.get_address(),
00082 #ifndef SGI
00083                        (socklen_t *)&addr_len);
00084 #else //def SGI
00085     &addr_len);
00086 #endif //ndef SGI
00087 if (socket_fd <= 0)
00088     PLERROR("Failure to connect with client");
00089 
00090 
00091 pipe.attach(socket_fd);
00092 //following commented out since pipe is a PStream instead of an fstream...
00093 //pipe.setbuf(0, 0); // Somehow this solves some problems
00094 }
00095 
00096 // Called from the client program to establish communication
00097 // with the server.
00098 int
00099 establish_connection(int n_hosts, const char *hostnames[], int port_no)
00100 {
00101     struct sockaddr_in address;
00102     struct hostent *hostinfo;
00103 
00104     // Setup socket
00105     int server_socket = socket(AF_INET, SOCK_STREAM, 0);
00106     if (server_socket <= 0)
00107         PLERROR("Cannot create socket");
00108 
00109     address.sin_family = AF_INET;
00110     address.sin_port = htons(port_no);
00111 
00112     for (int i = 0; i < n_hosts; ++i) {
00113         hostinfo = gethostbyname(hostnames[i]);
00114         if (!hostinfo)
00115             inet_pton(AF_INET, hostnames[i], &address.sin_addr);
00116         //address.sin_addr.s_addr = inet_addr(hostnames[i]);
00117         else
00118             address.sin_addr = *(struct in_addr *)*hostinfo->h_addr_list;
00119 
00120         // Connect to server
00121         if (connect(server_socket, (struct sockaddr *)&address, sizeof(address)))
00122             // Try next one
00123             continue;
00124             
00125         // Not sure this makes a difference here...
00126         int nodelay = 1;
00127         setsockopt(server_socket, IPPROTO_TCP, TCP_NODELAY, (char *)nodelay, sizeof(int));
00128 
00129         // Return socket descriptor
00130         return server_socket;
00131     }
00132     PLERROR("Connection to server failed");
00133     return -1; // Never reached
00134 }
00135 #endif // ~_MINGW_
00136 
00137 } // end of namespace PLearn
00138 
00139 
00140 /*
00141   Local Variables:
00142   mode:c++
00143   c-basic-offset:4
00144   c-file-style:"stroustrup"
00145   c-file-offsets:((innamespace . 0)(inline-open . 0))
00146   indent-tabs-mode:nil
00147   fill-column:79
00148   End:
00149 */
00150 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines