[C] Dubbio su recv e socket udp

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
TheKing
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 846
Iscrizione: venerdì 8 dicembre 2006, 11:32

[C] Dubbio su recv e socket udp

Messaggio 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!
ixamit
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 499
Iscrizione: giovedì 14 novembre 2013, 10:16

Re: [C] Dubbio su recv e socket udp

Messaggio 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).
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C] Dubbio su recv e socket udp

Messaggio 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).
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 6 ospiti