Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117

    [C/C++ - Linux] Ottenere indirizzo ip mittente da una recvfrom() con i socket udp

    Salve.
    Ho due semplici programmi udpclient e udpserver che utilizzano i socket udp; il server fa echo al client dei dati che arrivano. Ad ogni iterazione ambo i programmi stampano ip e numero di porta contenuti nelle strutture sockaddr_in che passano alle sendto() e ricevono dalle recvfrom().
    Vi posto qui i programmi:

    udpclient.c
    codice:
    #include <stdio.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <netinet/in.h>
    
    #define BUFFSIZE 255
    void Die(char *mess) { perror(mess); exit(1); }
    
    int main(int argc, char *argv[])
    {
    	int sock;
    	struct sockaddr_in echoserver;
    	struct sockaddr_in echoclient;
    	char buffer[BUFFSIZE];
    	unsigned int echolen, clientlen;
    	int received = 0;
    
     	if (argc != 4)
    	{
    		fprintf(stderr, "USAGE: %s <server_ip> <word> <port>\n", argv[0]);
    		exit(1);
    	}
    
    	/* Create the UDP socket */
    	if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    		Die("Failed to create socket");
    
    	/* Construct the server sockaddr_in structure */
    	memset(&echoserver, 0, sizeof(echoserver)); 	 	 /* Clear struct */
    	echoserver.sin_family = AF_INET;			 	 	  /* Internet/IP */
    	echoserver.sin_addr.s_addr = inet_addr(argv[1]);  /* IP address */
    	echoserver.sin_port = htons(atoi(argv[3])); 	 	 /* server port */
    
    
     	/* Send the word to the server */
     	echolen = strlen(argv[2]);
    	while(1)
    	{
    	 	if (sendto(sock, argv[2], echolen, 0, (struct sockaddr *) &echoserver, sizeof(echoserver)) != echolen)
    	 		Die("Mismatch in number of sent bytes");
    
    	 	/* Receive the word back from the server */
    		fprintf(stdout, "Received: ");
    		clientlen = sizeof(echoclient);
    		if ((received = recvfrom(sock, buffer, BUFFSIZE, 0, (struct sockaddr *) &echoclient, &clientlen)) != echolen)
    			Die("Mismatch in number of received bytes");
    
    		/* Check that client and server are using same socket */
    		if (echoserver.sin_addr.s_addr != echoclient.sin_addr.s_addr)
    			Die("Received a packet from an unexpected server");
    
    		buffer[received] = '\0'; 	 	  /* Assure null terminated string */
    		fprintf(stdout, buffer);
    		fprintf(stdout, "\n");
    		printf("%s:%i %s:%i\n",inet_ntoa(echoserver.sin_addr),ntohs(echoserver.sin_port),inet_ntoa(echoclient.sin_addr),ntohs(echoclient.sin_port));
    		sleep(1);
    	}
    	close(sock);
    	exit(0);
    }


    udpserver.c
    codice:
    #include <stdio.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <netinet/in.h>
    
    #define BUFFSIZE 255
    void Die(char *mess) { perror(mess); exit(1); }
    
    int main(int argc, char *argv[])
    {
    	int sock;
    	struct sockaddr_in echoserver;
    	struct sockaddr_in echoclient;
    	char buffer[BUFFSIZE];
    	unsigned int echolen, clientlen, serverlen;
    	int received = 0;
    
    	if (argc != 2)
    	{
    		fprintf(stderr, "USAGE: %s <port>\n", argv[0]);
    		exit(1);
    	}
    
    	/* Create the UDP socket */
    	if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    		Die("Failed to create socket");
    
    	/* Construct the server sockaddr_in structure */
    	memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */
    	echoserver.sin_family = AF_INET;	        /* Internet/IP */
    	echoserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* Any IP address */
    	echoserver.sin_port = htons(atoi(argv[1]));       /* server port */
    
    	/* Bind the socket */
    	serverlen = sizeof(echoserver);
    	if (bind(sock, (struct sockaddr *) &echoserver, serverlen) < 0)
    		Die("Failed to bind server socket");
    
    	  /* Run until cancelled */
    	while (1)
    	{
    		/* Receive a message from the client */
    		clientlen = sizeof(echoclient);
    		if ((received = recvfrom(sock, buffer, BUFFSIZE, 0, (struct sockaddr *) &echoclient,&clientlen)) < 0)
    			Die("Failed to receive message");
    
    	    fprintf(stderr, "Client connected: %s\n", inet_ntoa(echoclient.sin_addr));
    	    /* Send the message back to client */
    	    if (sendto(sock, buffer, received, 0,(struct sockaddr *) &echoclient, sizeof(echoclient)) != received)
    	      Die("Mismatch in number of echo'd bytes");
    
    		printf("%s:%i %s:%i\n",inet_ntoa(echoserver.sin_addr),ntohs(echoserver.sin_port),inet_ntoa(echoclient.sin_addr),ntohs(echoclient.sin_port));
    	}
    	return 0;
    }
    Eseguo i due programmi sulla stessa macchina, ma su due diverse shell:

    codice:
    [root@localhost socket]# ./udpserver 7000
    Client connected: 192.168.211.156
    0.0.0.0:7000 0.0.0.0:46166
    Client connected: 192.168.211.156
    0.0.0.0:7000 0.0.0.0:46166
    Client connected: 192.168.211.156
    0.0.0.0:7000 0.0.0.0:46166
    Client connected: 192.168.211.156
    0.0.0.0:7000 0.0.0.0:46166
    Client connected: 192.168.211.156
    0.0.0.0:7000 0.0.0.0:46166

    codice:
    [root@localhost socket]# ./udpclient 192.168.211.156 "prova" 7000
    Received: prova
    192.168.211.156:7000 192.168.211.156:7000
    Received: prova
    192.168.211.156:7000 192.168.211.156:7000
    Received: prova
    192.168.211.156:7000 192.168.211.156:7000
    Received: prova
    192.168.211.156:7000 192.168.211.156:7000
    Received: prova
    192.168.211.156:7000 192.168.211.156:7000
    Tuttavia, non capisco il perché, il client riceve mediante la recvfrom() la struttura echoclient di tipo sockaddr_in e ne riesce a stampare echoclient.sin_addr, mentre il server mediante la recvfrom() riceve echoclient e stampa echoclient.sin_addr dà in output 0.0.0.0. Eppure, la struttura echoclient deve contenere da qualche parte l'indirizzo ip del mittente, infatti passando tale struttura alla sendto() il server riesce ad inviare correttamente il messaggio di risposta al client. Qualcuno sa dirmi il perché? E' forse dovuto al fatto che eseguo i programmi sulla stessa macchina e quindi, l'indirizzo IP è uguale?

    Grazie.

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    466
    Non é la "soluzione" ma puoi arranguare cosi, (in locale)..
    codice server
    codice:
    char *address;
    ...
    echoserver.sin_port = htons(atoi(argv[1]));       /* server port */
    address = inet_ntoa(echoserver.sin_addr);
    ...
    printf("%s:%i %s:%i\n", address, ...

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Originariamente inviato da simo_85
    Non é la "soluzione" ma puoi arranguare cosi, (in locale)..
    codice server
    codice:
    char *address;
    ...
    echoserver.sin_port = htons(atoi(argv[1]));       /* server port */
    address = inet_ntoa(echoserver.sin_addr);
    ...
    printf("%s:%i %s:%i\n", address, ...
    Grazie!
    La cosa è alquanto strana ma se si vede la descrizione della inet_ntoa() nel man:
    The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation. The string is returned in a statically allocated buffer, which subsequent calls will overwrite.
    credo che sia dovuta al fatto che il parametro di ritorno è allocato staticamente e sovrascritto, ma non sono sicuro.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    466
    Cmq puoi anche recuperare l'indirizzo locale dell'interfaccia di rete che stai usando con la ioctl..
    Qui c'è appunto un esempio che può tornarti utile..

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Ho dato uno sguardo al codice... sembra una cosa utile. Non ho mai approfondito molto la ioctl().
    Più tardi lo provo. Grazie!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.