Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 20
  1. #1
    Utente di HTML.it L'avatar di N3llo
    Registrato dal
    Apr 2007
    Messaggi
    79

    [C] Invio di un struct su Unix socket

    Salve,
    Dopo aver scritto un semplice client/server in cui riesco a comunicare dei messaggi testuali mediante write ora vorrei inviare da un lato all'altro della comunicazione una struct.

    Leggendo parecchie cose mi son fatto un idea e mi pare di aver capito che la soluzione sia quella di serializzare la struct in un buffer e inviare il flusso di byte che verrà poi ricomposto in ricezione.

    Vi chiedo se qualcuno di voi ha del codice esemplificativo da passarmi per fare questo in C su una macchina che usa UBUNTU.

    Grazie

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,465
    Un codice pronto no, ma non dovrebbe essere difficile ... potresti provare a scrivere del codice e si controlla qui se qualcosa non va ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Vi chiedo se qualcuno di voi ha del codice esemplificativo da passarmi per fare questo in C su una macchina che usa UBUNTU.
    Parliamo di "Linux" è la stessa cosa
    Io molto tempo fa feci questo esercizio:
    Codice client:
    codice:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<bits/socket.h>
    #include<arpa/inet.h>
    #include<netinet/in.h>
    #include<netdb.h>
    
    int main(int argc, char *argv[])
    {
     int clientSocket;
     char msg_buffer[256] = "";
     struct sockaddr_in client;
     
     if(argc!=3)
     {
      fprintf(stderr, "\nusage: ./simple_client <server> <port nº>\n\n");
      return -1;
     }
    
     if((clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))!=-1)
      fprintf(stdout, "\nSocket Created!\n");
     else
      fprintf(stderr, "\nError creating socket...\n");
    
     bzero(&client, sizeof(client));
    
     client.sin_family = AF_INET;
     inet_aton(argv[1], NULL);
     client.sin_port = htons(atoi(argv[2]));
    
     if((connect(clientSocket, (struct sockaddr *)&client, sizeof(client))) != -1)
      fprintf(stdout, "Connected successfully to server!\n");
     else 
     {
      fprintf(stderr, "Error connecting to server...\n");
      close(clientSocket);
      exit(-1);
     }
     
     if((read(clientSocket, msg_buffer, sizeof(msg_buffer))!=-1))
      fprintf(stdout, "\nMessage received:\n<\"%s\">\n", msg_buffer);
     else
      fprintf(stderr, "Error receiving message...\n");
      
     close(clientSocket);
     return 0;
    }
    Codice server
    codice:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<bits/socket.h>
    #include<arpa/inet.h>
    #include<netinet/in.h>
    #include<netdb.h>
    
    #define MAX_CONNECTIONS 5
    
    const char message[100] = "I'm the server...";
    
    int main(int argc, char *argv[])
    {
     int serverSocket;
     struct sockaddr_in server;
     
     if(argc!=2)
     {
      fprintf(stderr, "\nusage: ./simple_server <port nº>\n\n");
      return -1;
     }
    
     if((serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))!=-1)
      fprintf(stdout, "\nSocket created!\n");
     else 
      fprintf(stderr, "\nError creating socket...\n");
      
     bzero(&server, sizeof(server));
     
     /*important set this parameters correctly*/
     server.sin_family = AF_INET;
     server.sin_addr.s_addr = htonl(INADDR_ANY);
     server.sin_port = htons(atoi(argv[1])); 
    
     if((bind(serverSocket, (struct sockaddr *)&server, sizeof(server))) != -1)
      fprintf(stdout, "Binding successfull!\n");
     else
      fprintf(stderr, "Binding Error...\n");
    
     /*listen for connections*/
     if((listen(serverSocket, MAX_CONNECTIONS))!=-1)
      fprintf(stdout, "Accepting connection on port %s\n", argv[1]);
     else
     {
      fprintf(stderr, "Error accepting connection on port %s\n", argv[1]);
      exit(-1);
     }
    
     /*accepting incoming connections */
     while(1)
     {
      struct sockaddr_in client;
      int clientSocket;
      int clientLength = sizeof(client);
    
       
      if((clientSocket = accept(serverSocket, (struct sockaddr *)&client, (socklen_t*)&clientLength))!=-1)
      {
       if((write(clientSocket, message, strlen(message)))!=-1)
       {
        fprintf(stdout, "\nMessage sent successfully!\n\n");
       }
      }
      else
      {
       fprintf(stderr, "Error sending message...\n");
       exit(1);
      }
    
      close(clientSocket);
      break;
     }
    
     fprintf(stdout, "Closing socket on port %s\n", argv[1]);
    
     close(serverSocket);
    
     fprintf(stdout, "#It's suggested wait few seconds to repeat the program ON THE SAME PORT,\n\tfor successfully re-execution.\n#Other port doesn't matter...\n\n");
    
     return 0;
    }
    Non usa una struttura come chiedi ti e usa una connessione locale sulla stessa macchin 127.0.0.1 (pero questo ultimo dettaglio è irrilevante, lo puoi lanciare anche da 2 pc differenti connessi tra loro) pero si basa sull'invio e ricezione di un messaggio. Spero che ti possa essere utile.
    Lanci il codice server e come argomento al main un nº di porta.
    Lanci il codice client con l'indirizzo del server (127.0.0.1) e lo stesso nº di porta.

  4. #4
    Utente di HTML.it L'avatar di N3llo
    Registrato dal
    Apr 2007
    Messaggi
    79
    Scusami, dopo che li ho compilati l'eseguibile mi da l'usage ma se uso il comando indicato mi dice che è sconosciuto.

    Ho provato chmod +x ma niente, come faccio a renderlo utilizzabile?

    //Risolto con la tua modifica al msg.

    Tra l'altro ti ringrazio molto ma cn un semplice msg di testo ci sono riuscito sia usando UNIX socket che Internet socket su localhost ::1, il mio problema è il passaggio della struct in uno stream di byte.

  5. #5
    Esempiodi esecuzione:
    Lanci prima il server in un terminale:
    codice:
    $ ./simple_server 5000
    
    Socket created!
    Binding successfull!
    Accepting connection on port 5000
    Lanci il client, altra finestra di terminale
    codice:
    ./simple_client 127.0.0.1 5000
    
    Socket Created!
    Connected successfully to server!
    
    Message received:
    <"I'm the server...">
    simo@localhost:~/Programming/dglnp/exs$
    
    $
    E questa sarà la continuazione dell'esecuzione del server, che nel frattempo sarà rimasto in attesa del client.
    codice:
    Message sent successfully!
    
    Closing socket on port 5000
    #It's suggested wait few seconds to repeat the program ON THE SAME PORT,
    	for successfully re-execution.
    #Other port doesn't matter...

  6. #6
    il mio problema è il passaggio della struct in uno stream di byte.
    Non c'è nessun problema..
    Metti che hai una struct che si chiama PIPPO
    Nel codice server:
    codice:
    write(clientSocket, PIPPO, sizeof(PIPPO))
    E nel codice client
    codice:
    read(clientSocket, PIPPO, sizeof(PIPPO))
    Più o meno dovrebbe essere questo l'approccio..
    Come ha detto oregon il meglio è che tu sviluppi un codice cosi lo si può esaminare assieme.

  7. #7
    Utente di HTML.it L'avatar di N3llo
    Registrato dal
    Apr 2007
    Messaggi
    79
    Ora se ho

    typedef struct {
    int a;
    char b;
    }

    per metterla in un buffer come posso fare?

    Scusa non avevo letto il tuo msg, ti spiego sto lavorando ad un Demone per proxy mobile ipv6 e non sono ferratissimo sulla programmazione,per non mettere direttamente le mani su quel mostro, vorrei provare a inviare semplici struct su client server scritto da me:


    codice:
    CLIENT!
    
    #include <stdio.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <unistd.h>
    
    int main(void)
    {
     struct sockaddr_un address;
     int socket_fd, nbytes;
     size_t address_length;
     char buffer[256];
    
     socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if(socket_fd < 0)
     {
      printf("socket() failed\n");
      return 1;
     }
     
     address.sun_family = AF_UNIX;
     address_length = sizeof(address.sun_family) +
                      sprintf(address.sun_path, "./demo_socket");
    
     if(connect(socket_fd, (struct sockaddr *) &address, address_length) != 0)
     {
      printf("connect() failed\n");
      return 1;
     }
    
     nbytes = sprintf(buffer, "hello from a client");
     write(socket_fd, buffer, nbytes);
     
     nbytes = read(socket_fd, buffer, 256);
     buffer[nbytes] = 0;
    
     printf("MESSAGE FROM SERVER: %s\n", buffer);
    
     close(socket_fd);
    
     return 0;
    }


    codice:
    SERVER
    
    #include <stdio.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int socket_fd, connection_fd;
    
    int connection_handler(int connection_fd)
    {
     int nbytes;
     char buffer[256];
    
     nbytes = read(socket_fd, buffer, 256);
     buffer[nbytes] = 0;
    
     printf("MESSAGE FROM CLIENT: %s\n", buffer);
     nbytes = sprintf(buffer, "hello from the server");
     write(socket_fd, buffer, nbytes);
     
     close(connection_fd);
     return 0;
    }
    
    int main(void)
    {
     struct sockaddr_un address;
     size_t address_length;
     pid_t child;
     
     socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if(socket_fd < 0)
     {
      printf("socket() failed\n");
      return 1;
     } 
    
     unlink("./demo_socket");
     address.sun_family = AF_UNIX;
     address_length = sizeof(address.sun_family) +
                      sprintf(address.sun_path, "./demo_socket");
    
     if(bind(socket_fd, (struct sockaddr *) &address, address_length) != 0)
     {
      printf("bind() failed\n");
      return 1;
     }
    
     if(listen(socket_fd, 5) != 0)
     {
      printf("listen() failed\n");
      return 1;
     }
    
     while((connection_fd = accept(socket_fd, 
                                   (struct sockaddr *) &address,
                                   &address_length)) > -1)
     {
      child = fork();
      if(child == 0)
      {
       /* now inside newly created connection handling process */
       return connection_handler(connection_fd);
      }
    
      /* still inside server process */
      close(connection_fd);
     }
    
     close(socket_fd);
     unlink("./demo_socket");
     return 0;
    }

  8. #8
    Utente di HTML.it L'avatar di N3llo
    Registrato dal
    Apr 2007
    Messaggi
    79
    Allora per capire come fare a creare uno stream ho fatto un programmino:

    codice:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h> 
    void main(){
    
    struct t {
      char *name;
      char *addr;
    } msg1,msg2;
    
    size_t SIZE=sizeof(msg1);
    char packed1[SIZE];
    char packed2[SIZE];
    
    
    msg1.name="Pluto";
    msg1.addr="Napoli";
    msg2.name="Pippo";
    msg2.addr="Roma";
    
    sprintf ( packed1, "%s|%s", msg1.name, msg2.addr );
    sprintf ( packed2, "%s|%s", msg2.name, msg2.addr );
    
    
    printf("Messaggio 1: %s",packed1);
    printf("\n");
    
    printf("Messaggio 2: %s",packed2);
    printf("\n");
    }

    Nei char packed ci sono le due struct che ho creato e fin qui tutto bene, ora se volessi fare l'operazione inversa come mi consigliate di fare?

  9. #9
    ora se volessi fare l'operazione inversa come mi consigliate di fare
    Non ho capito cosa intendi per operazione inversa..

  10. #10
    Utente di HTML.it L'avatar di N3llo
    Registrato dal
    Apr 2007
    Messaggi
    79
    Prendere dal buffer i byte e riportarli nella loro forma struct, deserializzare in ricezione.

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.