Newsgroup: it.comp.lang.c
Titolo: aiutino...

Salve, ho questi 2 codici un client e un server dove il client
dovrebbe mandare il file prova.txt al server, ma nel momento in cui il
server resta in ascolto e il client invia il file scompare il testo
del file e non viene inviato nulla... Perchè?? Grazie
CLIENT
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#define PORT 2080
main()
{
	int sock;
	sock =  socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in serv;
	serv.sin_port = htons(PORT);
	printf("%x %x\n",PORT,htons(PORT));
	serv.sin_family = AF_INET;
	serv.sin_addr.s_addr = inet_addr("127.0.0.1");
	printf("client connecting\n");
	connect(sock, (struct sockaddr *)&serv,sizeof(serv));
	char buf[50];
	FILE* fp = fopen("prova.txt","w");
	while(1){
		//bzero(buf,sizeof(buf));
		read(sock,buf,50);
		if(strcmp(buf,"quit1234")==0)
		{
			break;
		}
		fprintf(fp,"%s",buf);
	}
	fclose(fp);
}
SERVER
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#define PORT 2080
main()
{
	int sock1, sock2, clength;
	sock1 =  socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in serv, cli;
	serv.sin_family = AF_INET;
	serv.sin_port = htons(PORT);
	serv.sin_addr.s_addr = inet_addr("127.0.0.1");
	bind(sock1, (struct sockaddr *)&serv, sizeof(serv));
	listen(sock1, 5);
	clength = sizeof(cli);
	int i = 0;
	char buf[50];
	sock2 = accept(sock1, (struct sockaddr *)&cli, &clength);
	printf("\n Client Connected\n");
	FILE* fp = fopen("prova.txt", "r");
	while(!feof(fp)){
		//bzero(buf,sizeof(buf));
		fread(buf, sizeof(char), 50, fp);
		write(sock2, buf, 50);
	}
	write(sock2, "quit1234", 50);
	fclose(fp);
	return 0;
}


Non so se sia il problema, ma una cosa che salta subito all'occhio è
che sul client usi la fprintf() per stampare il buffer, cosa
ovviamente errata (pensaci un attimo ed arrivi subito a capire
perché). Usa la fwrite().
Ciao!

 	FILE* fp = fopen("prova.txt","w");
se prova.txt esiste, questo lo tronca ;D

file troncato a parte, un paio(*) di cosucce:
1) controlla il risultato delle chiamate di sistema (bind, listen, read, 
...), c'ï¿œ almeno un caso che debuggando un qualunque server capita 
sempre e rischia di darti grattacapi; inoltre il ciclo di lettura del 
file ï¿œ proprio sbagliato, se il file contiene 10 caratteri tu ne mandi 
altri quaranta che sono spazzatura...
2) read/write leggono bytes. Sottolineo _bytes_, non ï¿œ come fscanf che 
si ferma al blank/fgets che si ferma al newline, loro includono 
tranquillamente spazi/a capo/*qualsiasi* carattere finchï¿œ ne hanno letti 
abbastanza; per cui se pensavi di avere per esempio:
prima
seconda
quit1234
invisibile
lui legge in memoria "prima\nseconda\nquit1234\ninvisibile" e fa strcmp 
con "quit1234" - che fallisce sempre ;D
3) come ti hanno giï¿œ suggerito, read/fread *non* mettono '\0' alla fine 
delle stringhe
4) non avvilirti, ci siamo passati tutti, ma proprio tutti!
ciao
PS
feof() non dice se sei arrivato alla fine del file, ma solo se ci hai 
sbattuto contro durante l'ultima lettura; di nuovo, l'abbiamo dovuto 
imparare tutti da qualche nostro programma sbagliato.
(*) "paio" nel senso di "quattro", ovviamente ;)

 
Questa mi era sfuggita ;D


in questi 2 codici che ora posto dovrebbero non esserci più quegli
errori, però quando lancio "./client localhost nomefile" il client me
lo invia e il server mi dà come risposta un errore di apertura del
file... perchè??
CLIENT
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define SERVER_PORT 12345 /* arbitrary, but client and server must
agree */
#define BUF_SIZE 4096     /* block transfer size */
int main ( int argc , char **argv )
{
    int c, s, bytes;
    char buf[BUF_SIZE];                  /* buffer for incoming file
*/
    struct hostent *h;                   /* info about server */
    struct sockaddr_in channel;          /* holds IP address */
    if ( argc != 3 ) fatal ( "Usage: client server-name file-name" );
    h = gethostbyname ( argv[1] );       /* look up host's IP address
*/
    if ( ! h ) fatal ( "gethostbyname failed" );
    s = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP );
    if (s < 0) fatal("socket");
    memset ( &channel , 0 , sizeof ( channel ) );
    channel.sin_family = AF_INET;
    memcpy ( &channel.sin_addr.s_addr , h->h_addr , h->h_length );
    channel.sin_port = htons ( SERVER_PORT );
    c = connect ( s, ( struct sockaddr * ) &channel , sizeof
( channel ) );
    if ( c < 0 ) fatal ( "connect failed" );
    /* Connection is now established. Send file name including 0 byte
at end. */
    write ( s , argv[2] , strlen ( argv[2] ) + 1 );
    /* Go get the file and write it to standard output. */
    while ( 1 )
    {
        bytes = read ( s , buf , BUF_SIZE ); /* read from socket */
        if ( bytes <= 0 ) exit ( 0 );        /* check for end of file
*/
        write ( 1 , buf , bytes );           /* write to standard
output */
    }
}
fatal ( char *string )
{
    printf ( "%s\n" , string );
    exit ( 1 );
}
SERVER
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/socket.h>
#include <netdb.h>
#define SERVER_PORT 12345 /* arbitrary, but client and server must
agree */
#define BUF_SIZE 4096     /* block transfer size */
#define QUEUE_SIZE 10
int main ( int argc , char *argv[] )
{
    int s, b, l, fd, sa, bytes, on = 1;
    char buf[BUF_SIZE];              /* buffer for outgoing file */
    struct sockaddr_in channel;      /* hold's IP address */
    /* Build address structure to bind to socket. */
    memset ( &channel , 0 , sizeof ( channel ) );      /* zero channel
*/
    channel.sin_family = AF_INET;
    channel.sin_addr.s_addr = htonl ( INADDR_ANY );
    channel.sin_port = htons ( SERVER_PORT );
    /* Passive open. Wait for connection. */
	s = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ); /* create socket
*/
	if ( s < 0 ) fatal ( "socket failed" );
	b = bind ( s, (struct sockaddr *) &channel , sizeof ( channel ) );
	if ( b < 0 ) fatal ( "bind failed" );
	l = listen ( s , QUEUE_SIZE );           /* specify queue size */
	if ( l < 0 ) fatal ( "listen failed" );
	  /* Socket is now set up and bound. Wait for connection and process
it. */
  while ( 1 )
  {
      sa = accept ( s , 0 , 0 );        /* block for connection
request */
      if ( sa < 0 ) fatal ( "accept failed" );
      read ( sa , buf , BUF_SIZE );     /* read file name from socket
*/
      /* Get and return the file. */
      fd = open ( buf , O_RDONLY );     /* open the file to be sent
back */
      if ( fd < 0 ) fatal ( "open failed" );
      while ( 1 )
      {
          bytes = read ( fd , buf , BUF_SIZE );    /* read from file
*/
          if ( bytes <= 0 ) break;                 /* check for end of
file */
          write ( sa , buf , bytes );              /* write bytes to
socket */
      }
      close ( fd );              /* close file */
      close ( sa );              /* close connection  */
  }
}
fatal ( char *string )
{
    printf ( "%s\n" , string );
    exit ( 1 );
}

 file... perchï¿œ??
Gli errori in effetti sono corretti (per paranoia, manca netinet/in.h 
nel server ma evidentemente ï¿œ incluso da qualche altro header).
Mi sembra che dovrebbe funzionare - di piï¿œ: compilo, lo faccio girare, e 
funziona!
Prova a scrivere il *motivo* in fatal, qsa tipo
fatal ( char *string )
{
     perror(string);
     exit (1);
}
oppure, includendo errno.h,
fatal ( char *string )
{
     if(errno != 0)
         fprintf(stderr, "%s: %s\n", string, strerror(errno));
     else
         fprintf(stderr, "%s\n", string);
     exit ( 1 );
}
come risultato, ti dice cosa perchï¿œ fopen() fallisce.
Dovendo sparare a caso, mi verrebbe da pensare che
1) scrivi il nome sbagliato (se sei su linux, ricordati che ï¿œ 
case-sensitive!), oppure
2) client e server girano in cartelle diverse.
Se ancora non ti torna, alcune cose che puoi provare sono:
1) aggiungere delle printf di debug, tipo printf("nomefile=\"%s\"\n", 
nomefile);
2) usa un debugger, tanto dovrai imparare
[3,4: non molto pertinenti, ma per il futuro ti serviranno]
3) usa "strace mioprogramma" se sei su linux, o ktrace su bsd, oppure (boh?)
4) su linux, usa valgrind: ï¿œ uno di quei programmi che vale la pena di 
installare linux (anche in una macchina virtuale) solo per usarlo, ti 
domanderai come facevi senza ;D
Buon lavoro!

 Buon lavoro!
server e client li ho messi in 2 cartelle diverse, il file di testo
l'ho messo sulla cartella server, e quando lancio il client che
richiede quel file FUNZIONA!! il testo del file viene stampato a
video.... ora però ho un ultimo problema vorrei risolvere il problema
della terminazione del sever nel senso che il client dopo aver
stampato il file si chiude, mentre il server rimane in esecuzione e
per farlo terminare devo dare ctrl+c. Vorrei che appena il client si
chiude, si chiudesse anche il server magari anche con un messaggio del
tipo "invio riuscito"...

 tipo "invio riuscito"...
Scommmetto che 0.1 secondi dopo aver cliccato su "Invia" ti ï¿œ venuto in 
mente perchï¿œ il server rimane in esecuzione, e hai lanciato un "DOH!" da 
far venire giï¿œ i muri...

 far venire giù i muri...
non ti ho capito???