// remote_server.c -- Written by Curtis Olson // -- for CSci 5502 #include #include #include // for stat() #include #include // bind #include #include #include #include #include #include #define MAXBUF 1024 static double lat = 0.0; static double lon = 0.0; static double dy = 0.0; static int pass = 0; int make_socket (unsigned short int* port) { int sock; struct sockaddr_in name; socklen_t length; // Create the socket. sock = socket (PF_INET, SOCK_STREAM, 0); if (sock < 0) { perror ("socket"); exit (EXIT_FAILURE); } // Give the socket a name. name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = 0 /* htons (port) */; name.sin_addr.s_addr = htonl (INADDR_ANY); if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { perror ("bind"); exit (EXIT_FAILURE); } // Find the assigned port number length = sizeof(struct sockaddr_in); if ( getsockname(sock, (struct sockaddr *) &name, &length) ) { perror("Cannot get socket's port number"); } *port = ntohs(name.sin_port); return sock; } #if 0 // better move this to client // return true if file exists static bool file_exists( const string& file ) { struct stat buf; if ( stat( file.c_str(), &buf ) == 0 ) { return true; } else { return false; } } // check if the specified tile has data defined for it static bool has_data( const string& path, const FGBucket& b ) { string dem_file = path + ".dem" + "/Scenery/" + b.gen_base_path() + "/" + b.gen_index_str() + ".dem"; if ( file_exists( dem_file ) ) { return true; } dem_file += ".gz"; if ( file_exists( dem_file ) ) { return true; } return false; } #endif // initialize the tile counting system void init_tile_count() { // pre-pass pass = 0; // initial bogus value lat = 100; // determine tile height FGBucket tmp1( 0.0, 0.0 ); dy = tmp1.get_height(); } // return the next tile long int get_next_tile( const string& work_base, const string& output_base ) { FGBucket b; static double shift_over = 0.0; static double shift_up = 0.0; // cout << "lon = " << lon << " lat = " << lat << endl; if ( lat > 90.0 ) { ++pass; if ( pass == 1 ) { shift_over = 0.0; shift_up = 0.0; } else if ( pass == 2 ) { shift_over = 1.0; shift_up = 0.0; } else if ( pass == 3 ) { shift_over = 0.0; shift_up = 1.0; } else if ( pass == 4 ) { shift_over = 1.0; shift_up = 1.0; } else { return -1; } // reset lat lat = -89.0 + (shift_up*dy) - (dy*0.5); // reset lon FGBucket tmp( 0.0, lat ); double dx = tmp.get_width(); lon = -180 + (shift_over*dx) + (dx*0.5); cout << "starting pass = " << pass << " with lat = " << lat << " lon = " << lon << endl; } // if ( ! start_lon ) { // lon = -180 + dx * 0.5; // } else { // start_lon = false; // } if ( lon > 180.0 ) { // increment to next row // skip every other row (to avoid two clients working on // adjacent tiles) lat += 2.0 * dy; FGBucket tmp( 0.0, lat ); double dx = tmp.get_width(); lon = -180 + (shift_over*dx) + (dx*0.5); } b = FGBucket( lon, lat ); cout << "Bucket = " << b << " (" << pass << ")" << endl; // increment to next tile FGBucket tmp( 0.0, lat ); double dx = tmp.get_width(); // skip every other column (to avoid two clients working on // adjacent tiles) lon += 2.0 * dx; return b.gen_index(); } // display usage and exit void usage( const string name ) { cout << "Usage: " << name << " " << endl; exit(-1); } int main( int argc, char **argv ) { long int next_tile; int sock, msgsock, length, pid; fd_set ready; short unsigned int port; // quick argument sanity check if ( argc < 3 ) { usage( argv[0] ); } string work_base = argv[1]; string output_base = argv[2]; // initialize tile counter / incrementer init_tile_count(); // setup socket to listen on sock = make_socket( &port ); cout << "socket is connected to port = " << port << endl; // Specify the maximum length of the connection queue listen(sock, 10); for ( ;; ) { FD_ZERO(&ready); FD_SET(sock, &ready); // block until we get some input on sock select(32, &ready, 0, 0, NULL); if ( FD_ISSET(sock, &ready) ) { // printf("%d %d Incomming message --> ", getpid(), pid); // get the next tile to work on next_tile = get_next_tile(work_base, output_base); // cout << "next tile = " << next_tile << endl;; msgsock = accept(sock, 0, 0); // cout << "msgsock = " << msgsock << endl; // spawn a child pid = fork(); if ( pid < 0 ) { // error perror("Cannot fork child process"); exit(-1); } else if ( pid > 0 ) { // This is the parent close(msgsock); // clean up all of our zombie children int status; while ( (pid = waitpid( WAIT_ANY, &status, WNOHANG )) > 0 ) { // cout << "waitpid() returned " << pid << endl; } } else { // This is the child // cout << "new process started to handle new connection for " // << next_tile << endl; // reply to the client char message[MAXBUF]; sprintf(message, "%ld", next_tile); length = strlen(message); if ( write(msgsock, message, length) < 0 ) { perror("Cannot write to stream socket"); } close(msgsock); // cout << "process for " << next_tile << " ended" << endl; exit(0); } } } }