Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18

Discussione: socket C/C++

  1. #1
    Utente di HTML.it L'avatar di Poker32
    Registrato dal
    May 2001
    Messaggi
    240

    socket C/C++

    ciao a tutti, vorrei creare un'applicazione client-server in c/c++.
    penso che dovrò usare i socket, e fino a quà ci siamo.
    ma per usarli mi è parso di capire che servano i winsocket.
    mi potete spiegare meglio cosa sono e dove trovarli?

    ciao,Poker32!

  2. #2
    Credo di aver capito che tu voglia programmare con Windows e non con Linux, giusto?

    Qui c'e' un po' di materiale per WINSOCK

    http://www.google.it/search?hl=it&ie...ng+C%2B%2B&lr=

    Buon ravanamento

  3. #3
    Utente di HTML.it L'avatar di Poker32
    Registrato dal
    May 2001
    Messaggi
    240
    quindi ho trovato una spiegazione dei socket che ora mi studierò.
    cercando winsock2.h su google ho trovato una pagina con del codice c e sbra essere una libreria.
    a cosa mi può servire? winsock2.h è una libreria di c?

  4. #4
    Non una libreria ma un header file...

    E non riguards il C ANSI, ma secondo me essendo rinominato, sara' qualche modifica apportata da un programmatore a quel file...

  5. #5
    Utente di HTML.it L'avatar di Poker32
    Registrato dal
    May 2001
    Messaggi
    240
    c'è qualche bravo collega di forum che può inviarmi uno shcemino con le chiamate da eseguire per creare il server e il client???
    non mi serve un esempio di server-client ma solo uno schema con le funzione che i due devono chiamare per poter comunicare...

    mi date una mano???

  6. #6
    Utente di HTML.it L'avatar di Poker32
    Registrato dal
    May 2001
    Messaggi
    240
    up

  7. #7
    Questo è il template (assolutamente portabile, a differenza delle funzioni pure di Winsock o dell'uso di MFC) che uso per i server, l'unica cosa da cambiare è la funzione LANCIA_UN_THREAD e il fatto di usare dei metodi (dipendenti dal sistema) per ricevere segnalazioni di fine del programma (altrimenti dal loop non esci mai)

    codice:
    #define SERVERPORT 10202 /* la porta TCP da usare */
    #define MAX_CONN_PENDING 5  /* max connessioni in attesa del server */
    
    void main ()
    { 
      int  sfd, tfd;                
      int  i;
      struct  sockaddr_in  sa, isa; 
      struct  hostent  *hp;         
      
      /* chiede l'indirizzo del local host */
      gethostname(localhost,MAXHOSTNAME);
      if ((hp=gethostbyname(localhost))==NULL)  {
         perror("Impossibile ottenere nome host locale\n");
         exit(1);
        }
    
      /* inserisce il socket number dentro la struttura del socket */
      sa.sin_port=htons((short int) SERVERPORT);
    
      /* costruisce la struttura che contiene l'indirizzo del local host */ 
      memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
      
      sa.sin_family=hp->h_addrtype;
    
      /* richiede un descrittore di socket */
      if (( sfd=socket(hp->h_addrtype, SOCK_STREAM, 0))<0 )   {
         perror ("errore apertura socket \n");
         exit(1);
      }
    
      /* fa il bind alla service port */
      if (bind(sfd,(struct sockaddr*) &sa, sizeof (sa))<0)   {
         perror("bind rifiutato\n");
         exit(1);
         }
    
      /* massimo numero di connessioni accettate */
      listen(sfd, MAX_CONN_PENDING);   
       
      /* SERVER LOOP */
      
      while (1) 
      {
          i=sizeof (isa);      
          if (( tfd=accept(sfd,(struct sockaddr*) &isa, &i))<0)   {
              perror("errore accept \n");
              exit(1);     
              
          /* in tfd ho il file descriptor della connessione */
          LANCIA_UN_THREAD_PER_ESEGUIRE_LA_RICHIESTA(tfd);
      }         
      
    }
    Ah, in windows devi includere solo l'header <windows.h> e <winsock2.h>
    inoltre devi sempre scrivere nella main, prima di richiamare qualunque funzione socket, il seguente codice (copiato e incollato da MSDN
    codice:
    #ifdef WIN32
    
    	//code from MSDN
    	WORD wVersionRequested;
    	WSADATA wsaData;
    	int err;
     
    	wVersionRequested = MAKEWORD( 2, 2 );
     
    	err = WSAStartup( wVersionRequested, &wsaData );
    	if ( err != 0 ) {
    		/* Tell the user that we could not find a usable */
    	        /* WinSock DLL.                                  */
    		printf("Necessaria versione 2 di winsock\n");
    		return ;
    	}
     
    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */
     
    	if ( LOBYTE( wsaData.wVersion ) != 2 ||
            HIBYTE( wsaData.wVersion ) != 2 ) {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
    		printf("Necessaria versione 2 di winsock\n");
    	  WSACleanup( );
    	  return ; 
    }
    #endif

  8. #8
    E questo è lo schema per il client, anzi, è una funzione che mi sono scritto per facilitare la connessione al server, cerca di impostare la connessione in modo non blocking, se non riesce la lascia impostata in modo blocking, in certe circostanze è meglio avere socket bloccanti, comunque...

    codice:
    SOCKET Connect(char * host, short port, int timeout)
    {
    	unsigned long ulAddress;
    	int p;	
    	
    	HOSTENT hostent;
    	HOSTENT * h;
    
    	SOCKET s;
    	
    	TIMEVAL tv;
    	fd_set writefds;
    
    
    	struct sockaddr_in s_in;
    
    
    	if(host == NULL) 
    	{
    		return INVALID_SOCKET;
    	}
    	
    
    	//OPENS SOCKET
    	s = socket(AF_INET, SOCK_STREAM, 0); 
    	if (s == INVALID_SOCKET  ) 
    	{
    		return s;
    	}
    
    	//non blocking mode
    	p = 1;
    	p = ioctlsocket(s, FIONBIO  ,(ULONG*)&p);
    	
    	//prova a usare formato xxx.xxx.xxx.xxx ...
    	ulAddress = inet_addr(host);
    
    	if(ulAddress == INADDR_NONE)
    	{	//... errore: bisogna risolvere hostname		
    		h = gethostbyname(host);
    		if (h==NULL)
    		{
    			closesocket(s);			
    			return INVALID_SOCKET;
    		}
    	}
    	else
    	{	//... ok: gethostbyaddr
    		h = gethostbyaddr((char*) &ulAddress, sizeof(ulAddress), AF_INET);
    		if (h==NULL)
    		{
    			closesocket(s);
    			return INVALID_SOCKET;
    		}
    	}
    
    	memcpy(&hostent, h, sizeof(hostent));	
    	memset(&s_in, 0, sizeof(s_in)); 
    	memcpy(&s_in.sin_addr,hostent.h_addr,hostent.h_length);
    	s_in.sin_family = AF_INET;	
    	s_in.sin_port = htons(port);
    	
    	//PROVA A CONNETTERSI
    
    	if (connect(s,  (struct sockaddr*)&s_in, sizeof(s_in)) == SOCKET_ERROR) 
    	{ 
    		if (errno == EWOULDBLOCK) 
    //non ancora connesso (potrebbe ancora riuscire)
    		{
    
    			FD_ZERO(&writefds);
    			FD_SET(s, &writefds);
    	
    			tv.tv_sec = timeout;
    			tv.tv_usec = 0;
    			
    			p = select(0, NULL, &writefds, NULL, &tv); 
    //aspetta a vedere se riesce a collegarsi prima del timeout
    			if(p == 0) //failed
    			{
    				tv.tv_sec = 0;
    				p = select(0, NULL, NULL, &writefds, &tv); 
    				if(p == SOCKET_ERROR)//failed 								
    				{
    					closesocket (s);
    					return INVALID_SOCKET;				
    				}
    				else if(p==0)//failed ( timeout)
    				{
    					closesocket(s);
    					return INVALID_SOCKET;
    				}
    			}
    		}
    		else //connection failed
    		{	
    			closesocket(s);
    			return INVALID_SOCKET;
    		}			
    	}		
    	return s;
    
    }

  9. #9
    Una volta collegato al server, usa send e recv per inviare e ricevere i dati, leggi attentamente le avvertenze (MSDN o MAN), leggere e scrivere in rete non è come leggere e scrivere su disco, usando il descrittore di socket.

    Ah, se compili su linux metti

    #define INVALID_SOCKET -1
    #define SOCKET int

    così è portabile da Windows

  10. #10
    Utente di HTML.it L'avatar di Poker32
    Registrato dal
    May 2001
    Messaggi
    240
    ho provato a compilarlo cosi:



    #include <stdlib.h>
    #include <stdio.h>
    #include <windows.h>
    #include <winsock2.h>


    #define SERVERPORT 10202 /* la porta TCP da usare */
    #define MAX_CONN_PENDING 5 /* max connessioni in attesa del server */



    void main ()
    {
    int sfd, tfd;
    int i;
    struct sockaddr_in sa, isa;
    struct hostent *hp;


    #ifdef WIN32

    //code from MSDN
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 2, 2 );

    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) {
    /* Tell the user that we could not find a usable */
    /* WinSock DLL. */
    printf("Necessaria versione 2 di winsock\n");
    return ;
    }

    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we */
    /* requested. */

    if ( LOBYTE( wsaData.wVersion ) != 2 ||
    HIBYTE( wsaData.wVersion ) != 2 ) {
    /* Tell the user that we could not find a usable */
    /* WinSock DLL. */
    printf("Necessaria versione 2 di winsock\n");
    WSACleanup( );
    return ;
    }
    #endif


    /* chiede l'indirizzo del local host */
    gethostname(localhost,MAXHOSTNAME);
    if ((hp=gethostbyname(localhost))==NULL) {
    perror("Impossibile ottenere nome host locale\n");
    exit(1);
    }

    /* inserisce il socket number dentro la struttura del socket */
    sa.sin_port=htons((short int) SERVERPORT);

    /* costruisce la struttura che contiene l'indirizzo del local host */
    memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);

    sa.sin_family=hp->h_addrtype;

    /* richiede un descrittore di socket */
    if (( sfd=socket(hp->h_addrtype, SOCK_STREAM, 0))<0 ) {
    perror ("errore apertura socket \n");
    exit(1);
    }

    /* fa il bind alla service port */
    if (bind(sfd,(struct sockaddr*) &sa, sizeof (sa))<0) {
    perror("bind rifiutato\n");
    exit(1);
    }

    /* massimo numero di connessioni accettate */
    listen(sfd, MAX_CONN_PENDING);

    /* SERVER LOOP */

    while (1)
    {
    i=sizeof (isa);
    if (( tfd=accept(sfd,(struct sockaddr*) &isa, &i))<0) {
    perror("errore accept \n");
    exit(1);

    /* in tfd ho il file descriptor della connessione */
    LANCIA_UN_THREAD_PER_ESEGUIRE_LA_RICHIES
    TA(tfd);
    }

    }



    ma mi da circo 70 errori: variabili non dichiarate, cast non eseguiti. sia nel file main.cpp che in winsock.h.

    cosa ho sbagliato....

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.