/* 
DO NOT CHANGE THIS PROGRAM:
It is is provided for transparency and compilation 
purposes only.

program name: versa-client.c
version 0.1

Author: Joel E. Rodriguez-Ramirez
joel@versamedium.com

Versamedium Web Services
http://www.versamedium.com/geoinverse/versa-ves.html

Modified:
August-20-2004		
October-28-2009
November 2 2009
January 13 2010 (minor rev.)

compile as follows:

gcc versa-client.c -lm -o versa-client

usage: 

./versa-client server_ip_address server_port new/old filename

example1 : 

./versa-client www.versamedium.com 8888 0 matrixAAA.dat (header and data are sended by the first time)

example2 : 

./versa-client www.versamedium.com 8888 1 matrixAAA.dat 23 (header is different data was sended before.)



Refer to documentation for more information:
http://www.versamedium.com/Versamedium-white-paper.pdf

DISCLAIMER. TO THE EXTENT ALLOWED BY LOCAL LAW, THIS 
VERSAMEDIUM SOFTWARE PRODUCT ("SOFTWARE") IS PROVIDED TO 
YOU "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
WHETHER ORAL OR WRITTEN, EXPRESS OR IMPLIED. VERSAMEDIUM 
SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OR CONDITIONS 
OF MERCHANTABILITY, SATISFACTORY QUALITY, NON-INFRINGEMENT 
AND FITNESS FOR A PARTICULAR PURPOSE.



IN NO EVENT WILL VERSAMEDIUM BE LIABLE FOR DIRECT, SPECIAL, 
INCIDENTAL, CONSEQUENTIAL OR OTHER DAMAGES (INCLUDING LOST 
PROFIT, LOST DATA, OR DOWNTIME COSTS), ARISING OUT OF THE 
USE, INABILITY TO USE, OR THE RESULTS OF USE OF THE SOFTWARE, 
WHETHER BASED IN WARRANTY, CONTRACT, TORT OR OTHER LEGAL 
THEORY, AND WHETHER OR NOT ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGES. Your use of the Software is entirely at your 
own risk. Should the Software prove defective, you assume the 
entire cost of all service, repair or correction.


*/

#include <sys/types.h>
#include <unistd.h>          
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>     /* socket command libraries needed by some compilers */
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <netdb.h>
#include <arpa/inet.h>


#define SIM_LENGTH 2000 /* number of integers to be written and read */

void whichip();

typedef __int8_t byte;

union float_bytes {
    byte b[sizeof (float)];
    float f;
           } ;
	   
char direccionip[INET6_ADDRSTRLEN];					    
char ipstr[INET6_ADDRSTRLEN];

int main(int argc, char **argv){ 
int sock,manda,inicial,i,j,posneg,largostring,completa,port,newold; /* socket file descriptor */
struct sockaddr_in cli_name; 
int count,len,discx,discy,discz,scheme,totaldat,tiempdelay;
int itersend;
float value; 
float temporal, valtemp,tempciel;
float modelmin,modelmax,tempcent,valorfloat;
float  alpha,beta,statrms;
int bandera,cuentai,tmpcount,icount,jcount,numdatos,numero,bytessend;
int numrows,numcols,van,valorcien,inichar,inic,iex,amplitud,precision,iter,rc,cuentaf;
int status,statval,statiter,numberfilename,filtx,filty,filtz,cuentafloat;
char * pch;
char payload[512];
char busy_str_in[6];   
char valstring[2000];
char statstring[512];
char tempstatstring[512];
char tempstring[2000];
char nada[512];
char apunte[512];
char buf[4096];
char str[3];
char partialsolfile[80];
char strll[80];
char string1[80];
char string2[80];
char string3[80];
char string4[80];
char string5[80];
char strremotecode[80];
char stringfilename[4096];
char stripnumber[80]; 
char message[80];
char datoc[4];
char IP_ADDRESS[INET6_ADDRSTRLEN];
int PORT;
char filename[80];
char cadenaflotantes[512];
char numerochar[4];
float rhoa[900];
float solucion[5000];
float partial_error[200];


int inttempcent, errval;
float *elnuevo;
int num_itera, best_itera;
float error_itera, best_itera_error; 	


FILE *matrizHAM, *matrizSOL, *lastSOL, *iterSOL, *partial_errors;
union float_bytes a_number;

if(argc == 1){
printf("\n Usage:\n");
printf("\n CASE I (calculate solution for the first time):\n");
printf("At least 4 arguments are required. Please do as follows:\n\n");        
printf("versaclient server_ip_address server_port new/old (0/1) filename\n\n");
printf("example :\n"); 
printf("versaclient 200.94.161.124 8888 0 data.dat\n");
printf("(header and data are sended by the first time)\n\n");
printf("\n CASE II (use a previously calculated solution):\n");
printf("5 arguments are required. Please do as follows:\n\n");
printf("versaclient server_ip_address server_port new/old (0/1) filename number_of_previously_computed_solution\n\n");
printf("example :\n"); 
printf("versaclient 200.94.161.124 8888 1 data.dat 34\n\n"); 
printf("(just header from \"data.dat\" is sended to server this time)\n");
printf("matrix and the previously calculated solution (34) as  initial condition\n");
printf("both matrix and solution i.e. versamedium_sol_34.dat are stored in server )\n\n");

exit(0);
}


strncpy(string1, argv[1], 40);
sscanf(string1, "%s", &stripnumber);


strncpy(string2, argv[2], 40);
sscanf(string2, "%d", &port);


strncpy(string3, argv[3], 40);
sscanf(string3, "%d", &newold);


if(newold==0){
strncpy(string4, argv[4], 40);
sscanf(string4, "%s", &filename);
printf("newold=0 %s\n",string4);

             }

if(newold==1){

strncpy(string4, argv[4], 40);
/*printf("%s\n",string4);*/
sscanf(string4, "%s", &filename);
printf("newold=1 %s\n",string4);


strncpy(string5, argv[5], 40);
/*printf("%s\n",string4);*/
sscanf(string5, "%d", &numberfilename);
printf("number of used solution = %s\n",string5);

             }


if((argc != 5) && (newold==0)){
printf("4 arguments are required. Please do as follows:\n\n");
printf("versa-client server_ip_address server_port new/old (0/1) filename\n\n");
printf("example :\n\n"); 
printf("versaclient 200.94.161.124 8888 0 data.dat\n\n");
printf("(header and data are sended by the first time)\n\n");
exit(0);
}


if((argc != 6) && (newold==1)){
printf("5 arguments are required. Please do as follows:\n\n");
printf("versaclient server_ip_address server_port new/old (0/1) filename number_of_previously_computed_solution.)\n\n");
printf("example :\n\n"); 
printf("versaclient 200.94.161.124 8888 1 data.dat 34\n\n"); 
printf("(just header from \"data.dat\" is sended this time)\n");
printf("matrix and initial condition are taken from a \n");
printf("previously calculated and stored number 34)\n\n");

exit(0);
}


printf("Versamedium Web Services. (client program) ");
printf("%c",'©');
printf("2005\n");
printf("by: Joel E. Rodriguez-Ramirez, Ph.D. joel@versamedium.com\n\n");


PORT = port;

printf("Client is alive and establishing socket connection.\n");
 
 
strcpy(direccionip,stripnumber);
whichip();

strcpy(IP_ADDRESS,ipstr);

  
  
  /* set the socket descriptor */
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    { perror ("Opening channel");
      close(sock);
      exit(1);
    }
      
  /* set the physical address (cli_name) of the socket descriptor */
  bzero(&cli_name, sizeof(cli_name)); /* initializes the address structure */
  cli_name.sin_family = AF_INET; /* socket family will be AF_INET (Internet) */
  cli_name.sin_addr.s_addr = inet_addr(IP_ADDRESS); /* sets the Internet
						       Protocol (IP) address
						       of the server */
  cli_name.sin_port = htons(PORT); /* sets the port on which the server will
				      establish the socket connection */

  /* connect to the socket */
  if (connect(sock, (struct sockaddr *)&cli_name, sizeof(cli_name)) < 0)
    { perror ("Establishing Connection.....");
      close(sock);
      exit(1);
    }


/*
Los datos son como sigue:
numrows: integer number of rows. (required).

numcols: integer number of cols. (required).

modelmin:floating point number that specifies the lower bound limit for the solution's possible values.

modelmax:floating point number that specifies the upper bound limit for the solution's possible values.

scheme: integer value, that specifies the kind of regularization (not required defaults to 0),
        regularization with 1st/2nd derivative for wich an alpha and regularization matrix value's are
	 required or dinamical reglarization, for wich an discretization space is 
	 required,.. actually 1-d,2-d are available.


1: Dinamical Regularization 1-D.
2: Dinamical Regularization 2-D. 
3: Dinamical Regularization 3-D.
4: First Derivative.
5: Second Derivative. 


Note: that the alpha and regularization are advanced options,
for more information refer to the Versamedium Web Services User's Manual.

discx : Discretization in x value.
discy : Discretization in y value. (0 for 1-D Dinamical Regularization (case 3 above)).
discz : Discretization in z value. (0 for 1-D and 2-D Dinamical Regularization (case 3 and 4 above)).

filtx : Filter wide value in x. 
filty : Filter wide value in y. (0 for 1-D Dinamical Regularization (case 3 above)).
filtz : Filter wide value in z. (0 for 1-D and 2-D Dinamical Regularization (case 3 and 4 above)).


beta: regularization parameter that is needed for Dinamical Regularization.
       (this value varies in between 0.0: without regularization and 1.0: full weighting regularization)

Above also note that: 

 discx=n in the 1-D case.
 discx*discy=n in the 2-D case.
 discx*discy*discz=n in the 3-D case. 
 
 
 bits of amplitude:   (defaults to 9, Note that the bigger the 
                      amplitude the larger the computation time):
		           
		      
 bits of presision:  (defaults to 9, Note that the bigger the 
                      presicion the larger the computation time):

 
 number of iterations:
 
 
 code : reserverd code
 
*/



matrizHAM=fopen(filename,"r");

strcpy(nada," ");

strcpy(valstring," ");

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &numrows);
printf("Matrix has %d rows.\n",numrows);
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &numcols);
printf("Matrix has %d columns.\n",numcols);
strcat(valstring," ");
strcat(valstring,tempstring);

	
numdatos= numrows;
numero= numcols;
totaldat=(numdatos*numero)+numdatos+numero;

  
fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%f", &modelmin);
printf("Solution vector will have an lower bound value of: %f \n",modelmin);
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%f", &modelmax);
printf("Solution vector will have an upper bound value of: %f \n",modelmax);  
strcat(valstring," ");
strcat(valstring,tempstring);



fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &scheme);
if(scheme==1)  printf("Regularization scheme %d (Dinamical Regularization 1-D).\n",scheme);
if(scheme==2)  printf("Regularization scheme %d (Dinamical Regularization 2-D).\n",scheme);
if(scheme==3)  printf("Regularization scheme %d (Dinamical Regularization 3-D).\n",scheme);
if(scheme==4)  printf("Regularization scheme %d (First Derivative).\n",scheme);  
if(scheme==5)  printf("Regularization scheme %d (Second Derivative).\n",scheme);
  strcat(valstring," ");
  strcat(valstring,tempstring);
  


fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &discx);
printf("Discretization in x value: %d\n",discx);
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &discy);
printf("Discretization in y value: %d\n",discy);
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &discz);
printf("Discretization in z value: %d\n",discz);
strcat(valstring," ");
strcat(valstring,tempstring);


fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &filtx);
printf("filtx : Filter wide value in x: %d\n",filtx);
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &filty);
printf("filty : Filter wide value in y: %d\n",filty);
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &filtz);
printf("filtz : Filter wide value in z: %d\n",filtz);
strcat(valstring," ");
strcat(valstring,tempstring);


fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%f", &beta);
printf("Regularization beta value = %f\n",beta);  
strcat(valstring," ");
strcat(valstring,tempstring);


fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &amplitud);
printf("bits of amplitude : %d\n",amplitud);	
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &precision);
printf("bits of precision : %d\n",precision);	
strcat(valstring," ");
strcat(valstring,tempstring);

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%d", &iter);
printf("number of iterations : %d\n",iter);  
strcat(valstring," ");
strcat(valstring,tempstring);

   
fscanf(matrizHAM,"%s\n",&tempstring);
printf("Reserved parameter value = %s \n",tempstring);  
strcat(valstring," ");  
strcat(valstring,tempstring);


strcat(valstring," ");
strcat(valstring,string3);
   
   

if(newold==0){ /*new file*/
      strcat(valstring," ");	 
      strcat(valstring,string4); 

}



if(newold==1){/*old file */

      strcat(valstring," ");	 
      strcat(valstring,string4); 

      strcat(valstring," ");	 
      strcat(valstring,string5); 


             }




/* Send Parameters */

largostring=strlen(valstring);
for(completa=1;completa<(512-largostring);completa++) strcat(valstring," ");
send(sock,(char *)valstring,512,0);


/*Start authorizing */
recv(sock,(char *)payload ,512, 0); 
printf("\n****************************************************************\n");
printf("\n %s \n",payload);
printf("\n****************************************************************\n");


/*Start authorizing */




if(newold==0){ 

strcpy(valstring," ");

bandera=0;
van=1;


tempciel=((float) totaldat)/(100.0);
valorcien=(int) tempciel;

printf("\nStarting data transfer to server.\n");
printf("sending %d floating point single precision numbers.\n",totaldat);
printf("Note: Server may be busy processing other requests,\n");
printf("in wich case data transfer rate may vary. \n");


strcpy(buf,"=> ");
strcat(buf," ");	   
strcat(buf," 0 ");
strcat(buf," \%");


 for(inichar=0;inichar<strlen(buf);inichar++) {
	 putchar(buf[inichar]);	 
	 fflush(stdout);
	
			                      }



cuentafloat=0;
bandera=0; 


for(j=1;j<(totaldat+1);j++) {

fscanf(matrizHAM,"%s\n",&tempstring);
sscanf(tempstring, "%e", &temporal);

valorfloat=temporal;

posneg=0;
  if(temporal<0.0) {temporal=-temporal;posneg=1;}
  if(temporal<1.0e-43){
  if(posneg) valorfloat=-1.0e-43;
  else valorfloat=1.0e-43;
                      }
	       

a_number.f=valorfloat;


if(cuentafloat<512) {
cadenaflotantes[cuentafloat]=a_number.b[0];
cadenaflotantes[cuentafloat+1]=a_number.b[1];
cadenaflotantes[cuentafloat+2]=a_number.b[2];
cadenaflotantes[cuentafloat+3]=a_number.b[3];
                    }

cuentafloat=cuentafloat+4;

if((cuentafloat >= 511) || ((j)==(totaldat))){
                                        bandera=1;
                                              }


 if(bandera==1){

bytessend=send(sock,(char *)cadenaflotantes,512,0);
recv(sock,(char *)datoc ,4, 0);



strcpy(cadenaflotantes,"");
memset(&cadenaflotantes,0, 512);
bandera=0;
cuentafloat=0;

                }





if(j==(van*valorcien)){
tempcent=(float) j;
tempcent=tempcent/((float) totaldat);
inttempcent=(int) (tempcent*100.0);
van=van+1;

putchar('\r');
for(;inichar>0;inichar--) putchar(' ');
putchar('\r');



sprintf(str, "%d",inttempcent);
 
if((((int) inttempcent)>=0) && ((((int) inttempcent)<=10))) strcpy(buf,"[=> ");
if((((int) inttempcent)>10) && ((((int) inttempcent)<=20))) strcpy(buf,"[==> ");
if((((int) inttempcent)>20) && ((((int) inttempcent)<=30))) strcpy(buf,"[===> ");
if((((int) inttempcent)>30) && ((((int) inttempcent)<=40))) strcpy(buf,"[====> ");
if((((int) inttempcent)>40) && ((((int) inttempcent)<=50))) strcpy(buf,"[=====> ");
if((((int) inttempcent)>50) && ((((int) inttempcent)<=60))) strcpy(buf,"[======> ");
if((((int) inttempcent)>60) && ((((int) inttempcent)<=70))) strcpy(buf,"[=======> ");
if((((int) inttempcent)>70) && ((((int) inttempcent)<=80))) strcpy(buf,"[========> ");
if((((int) inttempcent)>80) && ((((int) inttempcent)<=90))) strcpy(buf,"[=========> ");
if((((int) inttempcent)>90) && ((((int) inttempcent)<=100))) strcpy(buf,"[==========> ");


strcat(buf," ");	   
strcat(buf,str); 
strcat(buf," "); 
strcat(buf,"%");
strcat(buf," ]"); 
 
 
	for(inichar=0;inichar<strlen(buf);inichar++) {
		                     putchar(buf[inichar]);	
		                     fflush(stdout);
		
	                                             }
                          }
			  
                                  }  /* fin de for(j=1;..)		   */
			
		    
 
printf("\n\n 100 %c finished sending data.\n",'%');
printf("computing solutions, process started.\n\n");
  

/* Finished sending Data */

newold=10; /*get out of this if Fin if(newold==0){  */

              }/*finish newold sending new data */

fclose(matrizHAM);

strcpy(buf,"busy.... please wait ");
 
bandera=1;

while(bandera){

bytessend=send(sock,(char *)cadenaflotantes,512,0);

recv(sock,(char *) busy_str_in,6, 0);
memcpy((void *) apunte,(void *) busy_str_in,6);   



if(strncmp(apunte,"isbusy",5)==0) {

putchar('\r');
for(inic=0;inic<strlen(buf);inic++) putchar(' ');
putchar('\r');

for(inichar=0;inichar<strlen(buf);inichar++) {
		                     putchar(buf[inichar]);	
		                     fflush(stdout);
	                                     }

				  }
				  

if(strncmp(apunte,"nobusy",5)==0) bandera=0;
  
                 }
		 


bytessend=send(sock,(char *)cadenaflotantes,512,0);
recv(sock,(char *)datoc ,4, 0);

  
tiempdelay=5;
strcpy(statstring,"  ");
strcpy(tempstatstring,"  ");
strcpy(payload,"  ");


bytessend=send(sock,(char *)cadenaflotantes,512,0);
recv(sock,(char *)datoc ,4, 0);
	
printf("\nStarting to receive process status ....please wait:\n");

bzero(&apunte, sizeof(apunte));
	
bandera=1;


while(bandera){


sleep(1);
bytessend=send(sock,(char *)cadenaflotantes,512,0);

recv(sock,(char *)payload ,512, 0);


memcpy((void *) apunte,(void *) payload,512);   

  pch = strtok(apunte," ");
  sscanf(pch, "%d", &num_itera);


  pch = strtok(NULL," ");
  sscanf(pch, "%f", &error_itera);


  pch = strtok(NULL," ");
  sscanf(pch, "%d", &best_itera);

  
  pch = strtok(NULL," ");		         
  sscanf(pch, "%f", &best_itera_error);	         

  
printf("current iteration %d rms error = %f %c ; best iteration %d with rms error = %f %c\n",num_itera,error_itera,'%',best_itera,best_itera_error,'%');  
  
if(num_itera>=iter) bandera=0;
                 }
	


/***********************RECIEVE PARTIAL SOLUTIONS BEGIN*********************************/		  



for(itersend=1;itersend<iter+1;itersend++){


strcpy(partialsolfile,"./versamedium_partial_sol_");
sprintf(strll,"%d",itersend);
strcat(partialsolfile,strll);
strcat(partialsolfile,".dat");



bandera=1;
cuentai=1;

while(bandera){

strcpy(cadenaflotantes,"this is a test 1 echo ");
bytessend=send(sock,(char *)cadenaflotantes,512,0);
 recv(sock,(char *)payload ,512, 0);
   
bzero(&apunte, sizeof(apunte));
	
memcpy((void *) apunte,(void *) payload,512);   
 
for(cuentaf=0; cuentaf<512; cuentaf=cuentaf+4) {

numerochar[0] = apunte[cuentaf];
numerochar[1] = apunte[cuentaf+1];
numerochar[2] = apunte[cuentaf+2];
numerochar[3] = apunte[cuentaf+3];
elnuevo=(float*) &numerochar;
solucion[cuentai]=*elnuevo;
cuentai++;

                                               }

if(cuentai>=numero) bandera=0;


             }




 
 iterSOL=fopen(partialsolfile,"w");
 
 for(j=1;j<(numero+1);j++) {
           fprintf(iterSOL,"%e\n",solucion[j]);
                           }
 
 fclose(iterSOL);

                                            }


//printf("Fin recibio datos\n");		  
	
//printf("\n\nreturn_partial_solution well done. check_socket_status = 6\n");  
//getchar(); 
 	
		  
/**********************************RECIEVE PARTIAL SOLUTIONS END**********************************/
	
		  
/***********************RECIEVE PARTIAL ERRORS BEGIN*********************************/		  
printf("\nbegin receiving partial linear errors\n\n"); 

strcpy(cadenaflotantes,"this is a test 1 echo ");
bytessend=send(sock,(char *)cadenaflotantes,512,0);

 recv(sock,(char *)payload ,512, 0);

  
bzero(&apunte, sizeof(apunte));
memcpy((void *) apunte,(void *) payload,512);   

cuentai=0; 
for(cuentaf=0; cuentaf<512; cuentaf=cuentaf+4) {

numerochar[0] = apunte[cuentaf];
numerochar[1] = apunte[cuentaf+1];
numerochar[2] = apunte[cuentaf+2];
numerochar[3] = apunte[cuentaf+3];
elnuevo=(float*) &numerochar;
partial_error[cuentai]=*elnuevo;
cuentai++;

                                               }
 
 
 
partial_errors=fopen("partial_linear_errors.dat","w");
for(errval=0;errval<iter;errval++){ 
 
strcpy(partialsolfile,"./versamedium_partial_sol_");
sprintf(strll,"%d",(errval+1));
strcat(partialsolfile,strll);
strcat(partialsolfile,".dat");
 
printf("solution %s has linear rms error %f %c\n",partialsolfile,partial_error[errval],'%');
fprintf(partial_errors," %d  %f \n",(errval+1),partial_error[errval]);

                                      }
fclose(partial_errors);


printf("\n partial errors were written to local file partial_linear_errors.dat\n\n");

/***********************RECIEVE PARTIAL ERRORS ENDS *********************************/		  
		  
printf("receiving the best linear solution,... please wait.\n");


bandera=1;
cuentai=1;

while(bandera){


strcpy(cadenaflotantes,"this is a test 1 echo ");
bytessend=send(sock,(char *)cadenaflotantes,512,0);

recv(sock,(char *)payload ,512, 0);
   
bzero(&apunte, sizeof(apunte));
	
memcpy((void *) apunte,(void *) payload,512);   
 
for(cuentaf=0; cuentaf<512; cuentaf=cuentaf+4) {

numerochar[0] = apunte[cuentaf];
numerochar[1] = apunte[cuentaf+1];
numerochar[2] = apunte[cuentaf+2];
numerochar[3] = apunte[cuentaf+3];
elnuevo=(float*) &numerochar;
solucion[cuentai]=*elnuevo;
cuentai++;

                                               }

//cuentai=cuentai-1;
if(cuentai>=numero) bandera=0;


             }



send(sock,(char *)datoc,4,0);
recv(sock,(char *)payload ,512, 0); 


strcpy(filename,"");
sscanf(payload, "%s", &filename);


printf("\n****************************************************************\n");
printf("\n Best linear solution file:  %s \n",payload);
printf("\n****************************************************************\n");


printf("\nThere is no need to send the whole file next time. \n");
printf("(i.e. if only some header parameters change)\n\n");
printf("see http://www.versamedium.com/geoinverse/doc.html\n\n");


matrizSOL=fopen(filename,"w");
 
for(j=1;j<(numero+1);j++) {
	 valtemp=solucion[j];
	 fprintf(matrizSOL,"%e\n",valtemp);
                          }

fclose(matrizSOL);

printf("Name of file of last solution was written to lastsolname.txt\n");
printf("this name could be used in programs where recursion is needed\n");
printf("(i.e. nonlinear recursive processing)\n");

lastSOL=fopen("lastsolname.txt","w");
   
      fprintf(lastSOL,"%s\n",filename);
      
fclose(lastSOL);



send(sock,(char *)datoc,4,0);
recv(sock,(char *)datoc ,4, 0);


printf("\ndata was written in local directory.\n");
printf("...thank you for using Versamedium Web Services.\n\n");

  close(sock); /* close connection to socket */
  exit(0); /* exit with no errors */ 

} /* end of main */




void whichip()
{
	struct addrinfo hints, *res, *p;
	int status;
	

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
	hints.ai_socktype = SOCK_STREAM;

	if ((status = getaddrinfo(direccionip, NULL, &hints, &res)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
		
	}

	printf("IP addresses for %s:\n", direccionip);

	for(p = res;p != NULL; p = p->ai_next) {
		void *addr;
		char *ipver;

		// get the pointer to the address itself,
		// different fields in IPv4 and IPv6:
		if (p->ai_family == AF_INET) { // IPv4
			struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
			addr = &(ipv4->sin_addr);
			ipver = "IPv4";
		} else { // IPv6
			struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
			addr = &(ipv6->sin6_addr);
			ipver = "IPv6";
		}

		// convert the IP to a string and print it:
		inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
		printf("  %s: %s\n", ipver, ipstr);
	}

	freeaddrinfo(res); // free the linked list

	//return 0;
}











