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

    [C/C++ - Linux] Specificare/ricavare il numero di porta utilizzato da un client

    Salve.
    Ho un quesito da porvi. Sto riprendendo in questo periodo l'utilizzo delle socket in C in ambiente Linux (in verità, era un argomento che non avevo mai approfondito più di tanto).

    Guardando qualche semplice esempio tcp di client e server in cui il server è semplicemente in attesa su una porta e il client si collega ad esso per inviare un semplice messaggio, ho notato che il client non fa altro che invocare la funzione socket(...) per ottenere una socket e richiamare la funzione connect(...), a cui, tra le varie cose, va passata una struttura sockaddr_in in cui vanno specificate informazioni quali l'indirizzo e la porta del server. Direte voi, nulla di strano. Va be'... volevo solo capire qualche piccola cosina.
    1) Innanzitutto, una volta chiamata la funzione connect si può considerare la connessione già effettivamente instaurata? (ovvero, è stato fatto l'handshaking tcp?)
    2) Dato che il numero di porta sul client viene scelto a caso, c'è modo di rilevare da programma client (e magari anche da programma server) qual è il numero di porta utilizzato dal client? :master:
    3) Se sul client volessi scegliere io un particolare numero di porta locale dalla quale collegarsi al server, come dovrei fare?

    Grazie


    P.S. Se ritenete necessario che io riporti il codice degli esempi che avevo visto, cerco di ricopiarlo.

  2. #2
    Dato che il numero di porta sul client viene scelto a caso
    Come a caso, tu scegli l'indirizzo IP e la porta a cui connetterti. Quando esci di casa conosci la tua meta o esci a caso?
    c'è modo di rilevare da programma client (e magari anche da programma server) qual è il numero di porta utilizzato dal client
    Ovvio.
    Se il server si mette in ascolto per connessioni sulla porta nº 5000, un client per connettersi a tale server deve conoscere l'IP del server e il Nº PORTA.
    Se sul client volessi scegliere io un particolare numero di porta locale dalla quale collegarsi al server, come dovrei fare
    Sto riprendendo in questo periodo l'utilizzo delle socket in C in ambiente Linux (in verità, era un argomento che non avevo mai approfondito più di tanto
    Mi stai confondendo seriamente..

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Non ci siamo capiti... o meglio, non mi sono spiegato (effettivamente sono stato ambiguo).
    Quando parlo di "numero di porta sul client" non intendo il numero di porta di destinazione (è ovvio che il client deve conoscere il numero di porta del server), ma a sua volta utilizza un suo numero di porta. In ogni comunicazione client-server tcp ci dovrebbero essere le quattro informazioni fondamentali che sono: 1) IP Client; 2) Porta Client; 3) IP Server; 4) Porta Server.
    Sul client io specifico IP Server e Porta Server, ma le altre informazioni credo non siano necessarie. Ma se volessi ricavare il numero di porta utilizzato dal client nella comunicazione come devo fare?

    Spero di aver riformulato il tutto in modo più comprensibile.

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Mi autorispondo in parte, avendo trovato info in rete. Se ho ben capito, per specificare il numero di porta si può usare la funzione bind(...) anche sul client e non solo sul server. Il suo utilizzo sul client è opzionale. Appena ho un attimo di tempo provo anche a verificarlo programmando ma oggi ho un po' i problemi ad accedere a Linux.
    Tuttavia, laddove non specificassi la funzione bind(...) che numero di porta mi verrebbe assegnato? Come potrei scoprirlo da programma?

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Giusto per far capire di cosa parlavo, posto qui anche le semplicissime applicazioni client e server.


    codice:
    client.cpp
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <strings.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    
    #define MAXBUF 	 200
    #define SERVPORT 7777
    
    
    int main(int argc,char *argv[])
    {
    	char buf[MAXBUF];
    	hostent* hp;
    	sockaddr_in sin;
    	int sock;
    
    	if (argc!=2)
    	{
    		fprintf(stderr,"usage: ./client host\n");
    		exit(1);
    	}
    
    	hp=gethostbyname(argv[1]);
    	if (!hp)
    	{
    		fprintf(stderr,"client: host sconosciuto\n");
    		exit(1);
    	}
    
    	bzero((char*)&sin,sizeof(sin));
    	sin.sin_family=AF_INET;
    	bcopy(hp->h_addr,(char*)&sin.sin_addr,hp->h_length);
    	sin.sin_port=htons(SERVPORT);
    
    	if ((sock=socket(PF_INET,SOCK_STREAM,0))<0)
    	{
    		perror("client: errore in socket");
    		exit(1);
    	}
    
    	if (connect(sock,(sockaddr*)&sin,sizeof(sin)) <0)
    	{
    		perror("client: errore in connect");
    		close(sock);
    		exit(1);
    	}
    
    	while (fgets(buf,sizeof(buf),stdin))
    	{
    		buf[MAXBUF-1]='\0';
    		send(sock,buf,strlen(buf)+1,0);
    		recv(sock,buf,sizeof(buf),0);
    		fputs(buf,stdout);
    	}
    
    	return 0;
    }
    codice:
    server.cpp 
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <strings.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    
    #define MAXCONN		10
    #define MAXBUF		200
    #define SERVPORT	7777
    
    
    int main()
    {
    	char buf[MAXBUF];
    	sockaddr_in sin;
    	int sock,new_sock;
    	int dim;
    
    	bzero((char*)&sin,sizeof(sin));
    	sin.sin_family=AF_INET;
    	sin.sin_addr.s_addr=INADDR_ANY;
    	sin.sin_port=htons(SERVPORT);
    
    	if ((sock=socket(PF_INET,SOCK_STREAM,0))<0)
    	{
    		perror("server: errore in socket");
    		exit(1);
    	}
    
    	if (bind(sock,(sockaddr*)&sin,sizeof(sin))<0)
    	{
    		perror("server: errore in bind");
    		exit(1);
    	}
    	listen(sock,MAXCONN);
    
    	while (1)
    	{
    		if ((new_sock=accept(sock,(sockaddr *)&sin,(socklen_t *)&dim))<0)
    		{
    			perror("server: errore in accept");
    			exit(1);
    		}
    
    		while (dim=recv(new_sock,buf,sizeof(buf),0))
    		{
    			fputs(buf,stdout);
    			send(new_sock,buf,sizeof(buf),0);
    		}
    		close(new_sock);
    	}
    
    	return 0;
    }
    Nel client la porta locale non è scelta esplicitamente. Il comando netstat mi restituisce, ad esempio:

    codice:
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address               Foreign Address             State      
    tcp        0      0 192.168.211.142:7777        192.168.211.142:59834       ESTABLISHED 
    tcp        0      0 192.168.211.142:59834       192.168.211.142:7777        ESTABLISHED
    (nota: le applicazioni le sto facendo girare sulla stessa macchina)

    Si vede chiaramente il numero di porta del client, ovvero 59834, che non ho stabilito io e che cambia se rieseguo l'applicazione. Posso scoprire da programma (sia dal client che dal server) qual è questo numero di porta del client?

    Ora spero davvero che la cosa sia chiara.

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Originariamente inviato da oregon
    Forse questo

    http://www.cact.unile.it/facilities/...apilsu236.html

    ti può aiutare.
    Assolutamente perfetto.




    Riguardo la scelta invece del numero di porta sul client, ho utilizzato la bind anche nell'applicazione client, modificandola in questo modo (vedi grassetto):

    codice:
    client_mod1.cpp 
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <strings.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    
    #define MAXBUF 	 200
    #define SERVPORT 7777
    
    
    int main(int argc,char *argv[])
    {
    	char buf[MAXBUF];
    	hostent* hp;
    	sockaddr_in sin;
    	int sock;
    
    	if (argc!=2)
    	{
    		fprintf(stderr,"usage: ./client host\n");
    		exit(1);
    	}
    
    	hp=gethostbyname(argv[1]);
    	if (!hp)
    	{
    		fprintf(stderr,"client: host sconosciuto\n");
    		exit(1);
    	}
    
    	bzero((char*)&sin,sizeof(sin));
    	sin.sin_family=AF_INET;
    	bcopy(hp->h_addr,(char*)&sin.sin_addr,hp->h_length);
    	sin.sin_port=htons(SERVPORT);
    
    	if ((sock=socket(PF_INET,SOCK_STREAM,0))<0)
    	{
    		perror("client: errore in socket");
    		exit(1);
    	}
    
    	struct sockaddr_in sin2;
    
    	bzero((char *)&sin2,sizeof(sin2));
    	sin2.sin_family=AF_INET;
    	sin2.sin_addr.s_addr=INADDR_ANY;  //in dubbio su questa riga
    	sin2.sin_port=htons(6000);
    
    	if (bind(s,(sockaddr*)&sin2,sizeof(sin2))<0)
    	{
    		perror("client: errore in bind");
    		exit(1);
    	}
    
    
    	if (connect(sock,(sockaddr*)&sin,sizeof(sin)) <0)
    	{
    		perror("client: errore in connect");
    		close(sock);
    		exit(1);
    	}
    
    	while (fgets(buf,sizeof(buf),stdin))
    	{
    		buf[MAXBUF-1]='\0';
    		send(sock,buf,strlen(buf)+1,0);
    		recv(sock,buf,sizeof(buf),0);
    		fputs(buf,stdout);
    	}
    
    	return 0;
    }
    Ero in particolare indeciso su se sin2.sin_addr.s_addr andasse inizializzato a INADDR_ANY; l'ho ricopiata dal programma server, ma non so quanto abbia senso sul client (in ogni caso, il client funziona). Secondo voi va inizializzata così? :master:

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 © 2024 vBulletin Solutions, Inc. All rights reserved.