int Trick::VariableServerThread::send_list_size() { char buf1[12] ; unsigned int msg_type ; int var_count; // send number of variables var_count = vars.size(); if (binary_data) { // send in the binary message header format: // <message_indicator><message_size><number_of_variables> msg_type = VS_LIST_SIZE; memcpy(buf1, &msg_type , sizeof(msg_type)) ; memset(&(buf1[4]), 0, sizeof(int)); // message size = 0 memcpy(&(buf1[8]), &var_count, sizeof(var_count)); if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d event variables\n", &connection, connection.client_tag, var_count); } tc_write(&connection, (char *) buf1, 12); } else { // ascii sprintf(buf1, "%d\t%d\n", VS_LIST_SIZE, var_count); if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending number of event variables:", &connection, connection.client_tag) ; message_publish(MSG_NORMAL, "%s\n", buf1); } tc_write(&connection, (char *) buf1, strlen(buf1)); } return 0 ; }
/** @par Detailed Design: */ int Trick::MonteCarlo::shutdown() { /** <ul><li> If this is a slave, run the shutdown jobs. */ if (enabled && is_slave()) { connection_device.port = master_port; if (tc_connect(&connection_device) == TC_SUCCESS) { int exit_status = MonteRun::COMPLETE; if (verbosity >= ALL) { message_publish(MSG_INFO, "Monte [%s:%d] Sending run exit status to master: %d\n", machine_name.c_str(), slave_id, exit_status) ; } int id = htonl(slave_id); tc_write(&connection_device, (char*)&id, (int)sizeof(id)); exit_status = htonl(exit_status); tc_write(&connection_device, (char*)&exit_status, (int)sizeof(exit_status)); run_queue(&slave_post_queue, "in slave_post queue"); tc_disconnect(&connection_device); } else { if (verbosity >= ERROR) message_publish( MSG_ERROR, "Monte [%s:%d] Failed to connect to master.\n", machine_name.c_str(), slave_id); } } return 0; }
int Trick::VariableServerThread::var_exists(std::string in_name) { char buf1[5] ; bool error = false ; unsigned int msg_type ; REF2* var_ref = ref_attributes(const_cast<char*>(in_name.c_str())); if ( var_ref == (REF2*)NULL ) { error = true; } if (binary_data) { /* send binary 1 or 0 */ msg_type = VS_VAR_EXISTS ; memcpy(buf1, &msg_type , sizeof(msg_type)) ; buf1[4] = (error==false); if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending 1 binary byte\n", &connection, connection.client_tag); } tc_write(&connection, (char *) buf1, 5); } else { /* send ascii "1" or "0" */ sprintf(buf1, "%d\t%d\n", VS_VAR_EXISTS, (error==false)); if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending:", &connection, connection.client_tag) ; message_publish(MSG_NORMAL, "%s\n", buf1); } tc_write(&connection, (char *) buf1, strlen(buf1)); } return(0) ; }
int cannon_send_position( CANNON* C ) { tc_write( &C->connection, (char *) &C->pos[0], sizeof(double)) ; tc_write( &C->connection, (char *) &C->pos[1], sizeof(double)) ; return 0 ; }
int Trick::VariableServerThread::transmit_file(std::string sie_file) { const unsigned int packet_size = 4095 ; FILE * fp ; unsigned int file_size ; unsigned int current_size = 0 ; unsigned int bytes_read ; char buffer[packet_size] ; int ret ; if (debug >= 2) { message_publish(MSG_DEBUG,"%p tag=<%s> var_server opening %s.\n", &connection, connection.client_tag, sie_file.c_str()) ; } if ((fp = fopen(sie_file.c_str() , "r")) == NULL ) { message_publish(MSG_ERROR,"Variable Server Error: Cannot open %s.\n", sie_file.c_str()) ; sprintf(buffer, "%d\t-1\n", VS_SIE_RESOURCE) ; tc_write(&connection , buffer , strlen(buffer)) ; return(-1) ; } fseek(fp , 0L, SEEK_END) ; file_size = ftell(fp) ; sprintf(buffer, "%d\t%d\n" , VS_SIE_RESOURCE, file_size) ; tc_write(&connection , buffer , strlen(buffer)) ; rewind(fp) ; // Switch to blocking writes since this could be a large transfer. if (tc_blockio(&connection, TC_COMM_BLOCKIO)) { message_publish(MSG_DEBUG,"Variable Server Error: Failed to set TCDevice to TC_COMM_BLOCKIO.\n"); } while ( current_size < file_size ) { bytes_read = fread(buffer , 1 , packet_size , fp) ; ret = tc_write(&connection , buffer , bytes_read ) ; if (ret != (int)bytes_read) { message_publish(MSG_ERROR,"Variable Server Error: Failed to send SIE file.\n", sie_file.c_str()) ; return(-1); } current_size += bytes_read ; } // Switch back to non-blocking writes. if (tc_blockio(&connection, TC_COMM_NOBLOCKIO)) { message_publish(MSG_ERROR,"Variable Server Error: Failed to set TCDevice to TC_COMM_NOBLOCKIO.\n"); return(-1); } return(0) ; }
void Trick::MonteCarlo::dispatch_run_to_slave(MonteRun *in_run, MonteSlave *in_slave) { if (in_slave && in_run) { current_run = in_run->id; if (prepare_run(in_run) == -1) { return; } in_slave->state = MonteSlave::RUNNING; connection_device.hostname = (char*)in_slave->machine_name.c_str(); connection_device.port = in_slave->port; if (tc_connect(&connection_device) == TC_SUCCESS) { std::stringstream buffer_stream; buffer_stream << run_directory << "/RUN_" << std::setw(5) << std::setfill('0') << in_run->id; std::string buffer = ""; for (std::vector<std::string>::size_type j = 0; j < in_run->variables.size(); ++j) { buffer += in_run->variables[j] + "\n"; } buffer += std::string("trick.set_output_dir(\"") + buffer_stream.str() + std::string("\");\n"); buffer_stream.str(""); buffer_stream << in_run->id ; buffer += std::string("trick.mc_set_current_run(") + buffer_stream.str() + std::string(");\n"); if (verbosity >= INFORMATIONAL) { message_publish(MSG_INFO, "Monte [Master] Dispatching run %d to %s:%d.\n", in_run->id, in_slave->machine_name.c_str(), in_slave->id) ; } int command = htonl(MonteSlave::PROCESS_RUN); tc_write(&connection_device, (char *)&command, (int)sizeof(command)); int num_bytes = htonl(buffer.length()); tc_write(&connection_device, (char*)&num_bytes, (int)sizeof(num_bytes)); tc_write(&connection_device, (char*)buffer.c_str(), (int)buffer.length()); tc_disconnect(&connection_device); ++in_slave->num_dispatches; in_slave->current_run = in_run; struct timeval time_val; gettimeofday(&time_val, NULL); in_run->start_time = time_val.tv_sec + (double)time_val.tv_usec / 1000000; ++in_run->num_tries; } else { in_slave->state = Trick::MonteSlave::DISCONNECTED; if (verbosity >= ERROR) { message_publish(MSG_ERROR, "Monte [Master] Lost connection to %s:%d while dispatching run.\n", in_slave->machine_name.c_str(), in_slave->id) ; } } } }
// MEMBER FUNCTION void Trick::MessageTCDevice::update( unsigned int level , std::string header , std::string message ) { std::vector < TCDevice *>::iterator it ; int nbytes ; int length ; std::string color_code ; /** @par Design Details: */ switch (level) { case MSG_NORMAL : color_code = "\033[00m" ; // normal break ; case MSG_INFO : color_code = "\033[32m" ; // green break ; case MSG_WARNING : color_code = "\033[33m" ; // yellow break ; case MSG_ERROR : color_code = "\033[31m" ; // red break ; case MSG_DEBUG : color_code = "\033[36m" ; // cyan break ; default : color_code = "\033[00m" ; // normal break ; } /** @li If this subscriber is not enabled, do nothing. Otherwise, it gets the update. */ if ( enabled && level < 100 ) { /** @li The message is composed as message header + message text */ if ( color ) { snprintf( combined_message , 20480 , "%s%s%s\033[00m" , header.c_str() , color_code.c_str() , message.c_str()) ; } else { snprintf( combined_message , 20480 , "%s%s" , header.c_str() , message.c_str()) ; } length = (int)strlen(combined_message) ; /** @li The message is broadcast to all socket connection this subscriber has. */ it = connections.begin() ; while ( it != connections.end() ) { nbytes = tc_write( *it, combined_message, length) ; /** @li All those connections that can not receive the message get disconnected. */ if ( nbytes != length ) { tc_disconnect(*it) ; it = connections.erase(it) ; } else { it++ ; } } } return ; }
int cannon_post_slave( /* RETURN: -- Always return zero */ CANNON_AERO* C) /* INOUT: -- Parameter */ { EXECUTIVE* E ; E = exec_get_exec(); /* Send slave results */ tc_write( &E->monte.work.data_conn, (char*) C, sizeof(CANNON_AERO) ); return(0) ; }
/* ENTRY POINT */ int target_slave_post( /* RETURN: -- 0 - OK, 1 - Error. */ TCDevice * tc_dev, /* INOUT: -- Iteration comm device. */ TargetBodyInit * init, /* INOUT: -- Target init state data. */ TargetBodyState * state, /* INOUT: -- Target body state data. */ TargetBodyData * target, /* INOUT: -- Targetting data. */ TargetBodyIteration * iterate ) /* INOUT: -- Iteration control data. */ { int dv_ret; /* Copy the initial state. */ V_COPY( iterate->v_init, init->velocity ); /* Call the delta-V computation. */ dv_ret = target_delta_v( state, target, iterate ); /* Send F(x) - which is in TargetBodyIteration. */ tc_write( mc_get_connection_device(), (char*)iterate, sizeof(TargetBodyIteration) ); /* Return to calling function. */ return( dv_ret ); }
int SatGraphicsComm::send_packet(Satellite* sat) { double packet[15]; // double packet[24]; packet[0] = sat->pos[0]; packet[1] = sat->pos[1]; packet[2] = sat->pos[2]; packet[3] = sat->vel[0]; packet[4] = sat->vel[1]; packet[5] = sat->vel[2]; packet[6] = sat->R[0][0]; packet[7] = sat->R[0][1]; packet[8] = sat->R[0][2]; packet[9] = sat->R[1][0]; packet[10] = sat->R[1][1]; packet[11] = sat->R[1][2]; packet[12] = sat->R[2][0]; packet[13] = sat->R[2][1]; packet[14] = sat->R[2][2]; // packet[15] = sat->Rplat[0][0]; // packet[16] = sat->Rplat[0][1]; // packet[17] = sat->Rplat[0][2]; // packet[18] = sat->Rplat[1][0]; // packet[19] = sat->Rplat[1][1]; // packet[20] = sat->Rplat[1][2]; // packet[21] = sat->Rplat[2][0]; // packet[22] = sat->Rplat[2][1]; // packet[23] = sat->Rplat[2][2]; tc_write(&connection, (char*)&packet, sizeof(packet)); return 0; }
int Trick::VariableServerThread::write_binary_data( int Start, char *buf1, int PacketNum ) { int i; int ret ; int HeaderSize, MessageSize; int NumVariablesProcessed; unsigned int msg_type , offset, len ; unsigned int size ; unsigned int swap_int ; char * address = 0 ; char* param_name; //remove warning for unused PacketNum... to be deleted. (void)PacketNum ; /* start the offset 4 bytes into the message, we'll subtract the sizeof offset at the end */ offset = sizeof(msg_type) + sizeof(offset) ; /* if we are here the msg_type is good, so send a 0, swapped or not 0 is still 0 */ msg_type = VS_VAR_LIST ; memcpy(buf1, &msg_type , sizeof(msg_type)) ; HeaderSize = sizeof(msg_type); offset += sizeof(unsigned int) ; HeaderSize += sizeof(unsigned int); for (i = Start; i < (int)vars.size() ; i++) { // data to send was copied to buffer in copy_sim_data address = (char *)vars[i]->buffer_out; size = vars[i]->size ; param_name = vars[i]->ref->reference; len = strlen(param_name) ; // when var_binary_nonames, do not put the variable names into the message to be sent if (binary_data_nonames) { MessageSize = sizeof(int) + sizeof(size) + size ; } else { MessageSize = sizeof(len) + len + sizeof(int) + sizeof(size) + size ; } /* make sure this message will fit in a packet by itself */ if ( (HeaderSize + MessageSize) > MAX_MSG_LEN ) { message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small (need %d) for symbol %s, SKIPPING IT.\n", &connection, MAX_MSG_LEN, (int)(HeaderSize + MessageSize), vars[i]->ref->reference ); continue; } if ( (offset + MessageSize) < MAX_MSG_LEN ) { if (byteswap) { if (!binary_data_nonames) { swap_int = trick_byteswap_int((int)len) ; memcpy(&buf1[offset] , &swap_int , sizeof(len)) ; offset += sizeof(len) ; memcpy(&buf1[offset] , param_name , (size_t)len) ; offset += len ; } swap_int = trick_byteswap_int(vars[i]->ref->attr->type) ; memcpy(&buf1[offset] , &swap_int , sizeof(int)) ; offset += sizeof(int) ; swap_int = trick_byteswap_int((int)size) ; memcpy(&buf1[offset] , &swap_int , sizeof(size)) ; offset += sizeof(size) ; /* TODO: There is a bug here, this call will want to swap the entire buffer, we may not have the whole buffer */ trick_bswap_buffer(&buf1[offset], address, vars[i]->ref->attr, 1); offset += size ; } else { int temp_i ; unsigned int temp_ui ; if (!binary_data_nonames) { memcpy(&buf1[offset] , &len , sizeof(len)) ; offset += sizeof(len) ; memcpy(&buf1[offset] , param_name , (size_t)len) ; offset += len ; } memcpy(&buf1[offset] , &vars[i]->ref->attr->type , sizeof(int)) ; offset += sizeof(int) ; memcpy(&buf1[offset] , &size , sizeof(size)) ; offset += sizeof(size) ; switch ( vars[i]->ref->attr->type ) { case TRICK_BITFIELD: temp_i = GET_BITFIELD(address , vars[i]->ref->attr->size , vars[i]->ref->attr->index[0].start, vars[i]->ref->attr->index[0].size) ; memcpy(&buf1[offset] , &temp_i , (size_t)size) ; break ; case TRICK_UNSIGNED_BITFIELD: temp_ui = GET_UNSIGNED_BITFIELD(address , vars[i]->ref->attr->size , vars[i]->ref->attr->index[0].start, vars[i]->ref->attr->index[0].size) ; memcpy(&buf1[offset] , &temp_ui , (size_t)size) ; break ; case TRICK_NUMBER_OF_TYPES: // TRICK_NUMBER_OF_TYPES is an error case temp_i = 0 ; memcpy(&buf1[offset] , &temp_i , (size_t)size) ; break ; default: memcpy(&buf1[offset] , address , (size_t)size) ; break ; } offset += size ; } } else { /* indicate that we're over the maximum size */ if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server buffer[%d] too small (need %d), sending multiple binary packets.\n", &connection, connection.client_tag, MAX_MSG_LEN, (int)(offset + MessageSize) ); } break ; } } /* adjust the header with the correct information reflecting what has been accomplished */ NumVariablesProcessed = i - Start; offset -= sizeof(offset) ; if (byteswap) { swap_int = trick_byteswap_int((int)offset) ; memcpy(buf1 + sizeof(msg_type) , &swap_int , sizeof(offset)) ; swap_int = trick_byteswap_int( NumVariablesProcessed ) ; memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &swap_int , sizeof(swap_int)) ; } else { memcpy(buf1 + sizeof(msg_type) , &offset , sizeof(offset)) ; memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &NumVariablesProcessed , sizeof( NumVariablesProcessed )) ; } if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %u binary bytes containing %d variables.\n", &connection, connection.client_tag, (unsigned int)(offset + sizeof(offset)), NumVariablesProcessed); } len = offset + sizeof(msg_type) ; ret = tc_write(&connection, (char *) buf1, len); if ( ret != (int)len ) { return(-1) ; } /* return the index to the next symbol to send or V->num_vars if all done */ return i; }
int Trick::VariableServerThread::write_data() { int ret; unsigned int i ; char buf1[ MAX_MSG_LEN ]; int len ; // do not send anything when there are no variables! if ( vars.size() == 0 or packets_copied == 0 ) { return(0); } /* Acquire sole access to vars[ii]->buffer_in. */ if ( var_data_staged and pthread_mutex_trylock(©_mutex) == 0 ) { unsigned int ii; void * temp_p; // Swap buffer_in and buffer_out for each vars[ii]. for ( ii = 0 ; ii < vars.size() ; ii++ ) { temp_p = vars[ii]->buffer_in; vars[ii]->buffer_in = vars[ii]->buffer_out; vars[ii]->buffer_out = temp_p; } var_data_staged = false; /* Relinquish sole access to vars[ii]->buffer_in. */ pthread_mutex_unlock(©_mutex) ; if (binary_data) { int Index = 0; int PacketNumber = 0; do { ret = write_binary_data( Index, buf1, PacketNumber ); if ( ret >= 0 ) { Index = ret ; } else { return(-1) ; } PacketNumber++; } while( Index < (int)vars.size() ); } else { /* ascii mode */ char val[MAX_MSG_LEN]; sprintf(buf1, "0\t") ; for (i = 0; i < vars.size(); i++) { ret = vs_format_ascii( vars[i] , val); if (ret < 0) { message_publish(MSG_WARNING, "%p Variable Server string buffer[%d] too small for symbol %s, TRUNCATED IT.\n", &connection, MAX_MSG_LEN, vars[i]->ref->reference ); } /* make sure this message will fit in a packet by itself */ if( strlen( val ) + 2 > MAX_MSG_LEN ) { message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small for symbol %s, TRUNCATED IT.\n", &connection, MAX_MSG_LEN, vars[i]->ref->reference ); val[MAX_MSG_LEN - 1] = '\0'; } len = strlen(buf1) ; /* make sure there is space for the next tab or next newline and null */ if( len + strlen( val ) + 2 > MAX_MSG_LEN ) { if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:", &connection, connection.client_tag, (int)strlen(buf1)) ; message_publish(MSG_NORMAL, "%s\n", buf1); } ret = tc_write(&connection, (char *) buf1, len); if ( ret != len ) { return(-1) ; } buf1[0] = '\0'; } strcat(buf1, val); strcat(buf1, "\t"); } len = strlen(buf1) ; if ( len > 0 ) { buf1[ strlen(buf1) - 1 ] = '\n'; if (debug >= 2) { message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:", &connection, connection.client_tag, (int)strlen(buf1)) ; message_publish(MSG_NORMAL, "%s\n", buf1); } ret = tc_write(&connection, (char *) buf1, (int)strlen(buf1)); if ( ret != (int)strlen(buf1) ) { return(-1) ; } } } } return (0); }
/* @details -# scan the incoming message for the command and requested path -# start the return message with a "{" -# if both a command and request is present -# if the command is "GET" -# if the path is "/" call get_top_page -# else if the path starts with "/vars" call get_vars -# else if the path starts with "/commands" call get_commands -# else create an error message reply -# else if the command is "POST" do something at some point. -# else create an error message reply -# else create an error message reply -# close the return message with a "}" -# create the http header for the reply message -# call tc_write to send the reply message */ void Trick::JSONVariableServerThread::parse_request() { // Need to protect against buffer overflow char command[32] ; char path[512] ; std::stringstream ss ; std::stringstream body ; int ret ; ret = sscanf(incoming_msg, "%s %s", command , path) ; body << "{" << std::endl ; if ( ret == 2 ) { //std::cout << "command = " << command << std::endl ; //std::cout << "path = " << path << std::endl ; if ( ! strcmp(command, "GET") ) { if ( ! strcmp(path, "/") ) { // send the top page ret = get_top_page(body) ; } else if ( ! strncmp(path, "/vars", 5)) { // get list of variables or value ret = get_vars(body, &path[5]) ; } else if ( ! strncmp(path, "/commands", 9)) { // get list of commands ret = get_commands(body, &path[9]) ; } else { ret = 404 ; body << " \"name\" : \"" << path << "\" ," << std::endl ; body << " \"message\" : \"Not Found\"" << std::endl ; } } else if ( ! strcmp( command, "POST") ) { //TODO: Allow setting variable values with POST. ret = 405 ; body << " \"verb\" : \"" << command << "\" ," << std::endl ; body << " \"message\" : \"Method not allowed\"" << std::endl ; } else { ret = 405 ; body << " \"verb\" : \"" << command << "\" ," << std::endl ; body << " \"message\" : \"Method not allowed\"" << std::endl ; } } else { ret = 400 ; body << " \"message\" : \"Bad Request\"" << std::endl ; } body << "}" << std::endl ; ss << "HTTP/1.1 " << ret ; switch (ret) { case 200: ss << " OK" ; break ; case 400: ss << " Bad Request" ; break ; case 404: ss << " Not Found" ; break ; case 405: ss << " Method Not Allowed" ; break ; default: ss << " Unknown" ; break ; } ss << std::endl ; ss << "Content-Type: application/json" << std::endl ; ss << "Content-Length: " << body.str().size() << std::endl << std::endl ; ss << body.str() ; //std::cout << ss.str() ; tc_write(&connection, (char *)ss.str().c_str() , ss.str().size()) ; }
int Trick::MonteCarlo::write(char* data, int size) { return tc_write(&connection_device, data, size); }
int main( int narg, char** args ) { TCDevice listen_device ; TCDevice connection ; int verbose ; int nbytes ; int num_packets ; char *msg ; int msg_len ; int i ; #if __WIN32__ FILETIME start, stop; LARGE_INTEGER temp_start, temp_stop, total ; #else struct timeval tp ; double time1, time2; #endif double sum_time ; #if __WIN32__ memset(&total,0,sizeof(LARGE_INTEGER)); #endif /* Parse args */ verbose = 0 ; if ( narg < 3 || narg > 4 ) { fprintf(stderr, "USAGE: tc_server <num_packets> <packet_size> [-v]\n"); exit(-1); } if ( narg == 4 ) { verbose = 1 ; } num_packets = atoi(args[1]) ; msg_len = atoi(args[2]) ; if ( msg_len < 1 || num_packets < 1 ) { fprintf(stderr, "USAGE: tc_server <num_packets> <packet_size> [-v]\n"); } /* Create message */ msg = (char*) malloc ( msg_len * sizeof(char)) ; for ( i = 0 ; i < msg_len ; i++ ) { msg[i] = '#' ; } /* Zero out devices */ memset(&listen_device, '\0', sizeof(TCDevice)); memset(&connection, '\0', sizeof(TCDevice)); /* Get an error handler */ if ( verbose ) { tc_error(&connection, 1) ; tc_error(&listen_device, 1) ; } /* Accept connection */ listen_device.port = 7000 ; tc_init(&listen_device) ; tc_accept(&listen_device, &connection); sum_time = 0 ; for ( i = 0 ; i < num_packets ; i++ ) { /* Get initial time */ #if __WIN32__ GetSystemTimeAsFileTime(&start); #else gettimeofday( &tp , (struct timezone *)NULL ) ; time1 = (double)(tp.tv_sec) + ( (double)(tp.tv_usec) / 1000000.0 ) ; #endif nbytes = tc_read(&connection, msg, msg_len) ; nbytes = tc_write(&connection, msg, msg_len) ; /* Get final time */ #if __WIN32__ GetSystemTimeAsFileTime(&stop); temp_start.LowPart = start.dwLowDateTime ; temp_start.HighPart = start.dwHighDateTime ; temp_stop.LowPart = stop.dwLowDateTime ; temp_stop.HighPart = stop.dwHighDateTime ; total.QuadPart = total.QuadPart + temp_stop.QuadPart - temp_start.QuadPart ; #else gettimeofday( &tp , (struct timezone *)NULL ) ; time2 = (double)(tp.tv_sec) + ((double)(tp.tv_usec) / 1000000.0 ) ; time2 = (double)(tp.tv_sec) + ((double)(tp.tv_usec) / 1000000.0 ) ; sum_time = sum_time + ( time2 - time1 ) ; #endif } #if __WIN32__ sum_time = (double)(total.QuadPart * 0.0000001 ) ; #endif fprintf(stderr, "Avg packet round trip : %lf \n", sum_time/(double)num_packets ); return 0 ; }