Pagina 1 di 1

[C] Dubbio su recv e socket udp

Inviato: lunedì 2 giugno 2014, 23:33
da TheKing
Ho questo due sorgenti:

Client.c

Codice: Seleziona tutto

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

#define BYTES_NR 64
#define MSG_NR 512


int main(int argc, char *argv[]) {
	char buf[BYTES_NR];
	char buf2[BYTES_NR];
	char msg[MSG_NR][BYTES_NR];
	char answ[MSG_NR][BYTES_NR];
	struct timeval xstime[MSG_NR];
	struct timeval xftime[MSG_NR];
	int i,sock,rval,length;
	unsigned long delay;
	struct sockaddr_in server,client;
	struct hostent *hp, *gethostbyname();
	
	if(argc !=3) {
		fprintf(stderr,"Usage: %s servername serverport\n",argv[0]);
		exit(-1);
	}
	
	for(i=0;i<MSG_NR;i++) {
		sprintf(&msg[i][0],"%d",i);
	}

	sock= socket(AF_INET,SOCK_DGRAM,0);
	if(sock<0) {
		perror("opening stream socket");
		exit(1);
	}
	
	client.sin_family= AF_INET;
	client.sin_addr.s_addr = INADDR_ANY;
	client.sin_port = htons(0);
	
	if (bind(sock,(struct sockaddr *)&client,sizeof(client)) <0) {
		perror("sending datagram message");
		exit(1);
	}
	
	length= sizeof(client);
	if(getsockname(sock,(struct sockaddr *)&server,(socklen_t *)&length)<0) {
		perror("getting socket name");
		exit(1);
	}
	
	printf("Socket port #%d\n",ntohs(client.sin_port));
	hp = gethostbyname(argv[1]);
	if (hp == 0) {
		fprintf(stderr,"%s :unknow host",argv[1]);
		exit(2);
	}
	
	bcopy( (char *)hp ->h_addr, (char *)&server.sin_addr,hp ->h_length);
	server.sin_family = AF_INET;
	server.sin_port = htons(atoi(argv[2]));
	for(i=0;i<MSG_NR;i++) {
	printf("ciclo-");
		strcpy(buf,msg[i]);
		gettimeofday(&xstime[i],NULL);
		
		if(sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&server, sizeof(server)) < 0)
			perror("sendto problem");
			
		if((rval = read(sock,buf2,sizeof(buf2)))<0)
			perror("reading stream message");
			
		strcpy(answ[i],buf2);
		gettimeofday(&xftime[i],NULL);
	}
	close(sock);
	
	for (i=0; i<MSG_NR; i++) {
		delay = (xftime[i].tv_sec-xstime[i].tv_sec)*1000000.+(xftime[i].tv_usec-xstime[i].tv_usec);
		printf("msg %d [%s]: %0.3f ms\n",i,answ[i],delay/1000.);
	}
	
	return 0;
}
Server.c

Codice: Seleziona tutto

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/timeb.h>
#include <string.h>
#include <unistd.h>

#define BYTES_NR 64
#define MSG_NR 512


int main(int argc, char *argv[]) {
	char buf[BYTES_NR];
	int sock,length;
	struct sockaddr_in server,client;
	int rval,i;
	
	if(argc !=2) {
		fprintf(stderr,"Usage: %s port\n",argv[0]);
		exit(-1);
	}

	sock = socket(AF_INET,SOCK_DGRAM,0);
	if(sock<0) {
		perror("opening stream socket");
		exit(1);
	}

	server.sin_family = AF_INET;
	server.sin_addr.s_addr= INADDR_ANY;
	server.sin_port = htons(atoi(argv[1]));
	if (bind(sock,(struct sockaddr *)&server,sizeof(server))<0) {
		perror("binding stream socket");
		exit(1);
	}
	

	length = sizeof(server);
	if(getsockname(sock,(struct sockaddr *)&server, (socklen_t *)&length)<0){
		perror("getting socket name");
		exit(1);
	}
	

	printf("Socket port #%d\n",ntohs(server.sin_port));
	printf("test");
	while(1) {
		do {
                        printf("test2");
			bzero(buf,sizeof(buf));
			rval = recvfrom(sock,buf,sizeof(buf), 0, (struct sockaddr *)&client, (socklen_t *)&length );

			if(rval<0)
				perror("reading stream message");
			i=0;
			if(rval==0)
				printf("Ending connection\n");
			else {
				printf("Message received: sending back\n");
				strcat(buf,"*");
				if (sendto(sock,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client))<0)
					perror("writing on stream socket");
			}
		} while(rval !=0);
	}
	return 0;
}
Nella parte server, come mai il printf che stampa "test", non entra in funzione prima che un client arrivi con una richiesta di invio messaggio? La stessa cosa vale per il secondo printf che stampa "test2".
Eppure la recvfrom è successiva a questi printf, probabilmente c'è qualcosa di concettuale che mi sfugge!

Re: [C] Dubbio su recv e socket udp

Inviato: martedì 3 giugno 2014, 18:18
da ixamit
TheKing ha scritto:Nella parte server, come mai il printf che stampa "test", non entra in funzione prima che un client arrivi con una richiesta di invio messaggio? La stessa cosa vale per il secondo printf che stampa "test2".
Eppure la recvfrom è successiva a questi printf, probabilmente c'è qualcosa di concettuale che mi sfugge!
Se aggiungi un carattere di new line oppure una fflush dopo le printf vedi l'output (prima della connessione del client).

Re: [C] Dubbio su recv e socket udp

Inviato: mercoledì 4 giugno 2014, 18:06
da SuperStep
per dare una risposta piu' esaustiva:

la printf e' una funzione line buffered, vale a dire che:
prima che quello che c'e' nel buffer della printf venga scaricato sul file stdout (e quindi lo vedi sul terminale), il buffer deve riempirsi o nel buffer deve essere presente il carattere di newline (\n).