Thread: Sending structures through the network

  1. #1
    Registered User Mortissus's Avatar
    Join Date
    Dec 2004
    Location
    Brazil, Porto Alegre
    Posts
    152

    Sending structures through the network

    Hi, I need to send different structures through the network, and be able to recover them at the other side. I do not know how to give each structure an unique identifier, so I can discover what is the structure after receiving it. The receiver will be waiting for specific structures, the problem is that the structures can arrive in any order, or some of them do not arrive at all, for example:

    Code:
    structure Basic {
        /* data */
    };
    
    structure AdvancedOne {
        /* data */
    };
    
    structure AdvancedTwo {
        /* data */
    };
    
    /* Generates data to the receiver */
    void sender()
    {
        Basic b;
        AdvancedTwo at;
    
        /* Initialize */
    
        char socket_buffer[MAX_SIZE];
        int current_size = 0;
        pack(&b, sizeof(b), socket_buffer, &current_size);
        pack(&at, sizeof(at), socket_buffer, &current_size);
    
        send(sock_fd, socket_buffer, current_size);
    }
    
    /* Decode data, it will be waiting for Basic and AdvancedOne */
    void receiver()
    {
        char buffer[MAX_SIZE];
        recv(sock_fd, buffer, sizeof(buffer), 0);
    
        Basic b;
        AdvancedOne ao;
    
        unpack(&b, sizeof(b), buffer);
        unpack(&ao, sizeof(ao), buffer); // Will generate an erro, that's ok, AdvOne was not sent
    }
    The unpack function would rely on the first 4 bytes (an int) to know what is unpacking (the identifier). My problem is that I do not know what is the best way to assign this ID. I could have specific pack functions for each type of structure, but, if possible, I would like to have only a pack function like:
    Code:
    void pack(void*, int, char*, int);
    In C++ I would perform something like:
    Code:
    struct B {
        static int ID;
    };
    int B::ID = 0;
    Any suggestions?

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Well, if you don't want to add an ID member to each of your structs, you could encapsulate them in another struct. Something like:
    Code:
    struct pack_s
    {
      int id;
      void *structdata;
    }
    Your pack() function would just create a new instance of the pack_s struct, assign the ID, and then assign the structdata pointer to point to the struct you're trying to pack.
    If you understand what you're doing, you're not learning anything.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Bear in mind that as well as a "pack" problem, you also have to be aware of "endian" as well.

    Unless you're sending huge volumes of data, I would suggest you send everything as a string.
    - it solves all the packing and alignment problems.
    - it is trivial to implement the encoder and decoder.
    - it is very easy to debug at the network level using say wireshark.

    Sure, when everything is working, and you need a bit of a boost on the bandwidth, then you can revert to more complicated binary encoding.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User Mortissus's Avatar
    Join Date
    Dec 2004
    Location
    Brazil, Porto Alegre
    Posts
    152
    Quote Originally Posted by itsme86 View Post
    Well, if you don't want to add an ID member to each of your structs, you could encapsulate them in another struct. Something like:
    Code:
    struct pack_s
    {
      int id;
      void *structdata;
    }
    Your pack() function would just create a new instance of the pack_s struct, assign the ID, and then assign the structdata pointer to point to the struct you're trying to pack.
    Thanks for the reply
    The problem isn't have the id inside each structure. The problem is that I want a generic pack function (void* parameter), but I want to be able to discover in the receiver, what struct it is. Basically, resuming: How can I make this C++ code in C (semantically):
    Code:
    struct A {
        static char id;
    };
    
    char A::id = 'A';
    
    // Or, could use a constructor
    
    struct A {
        A() { id = 'A'; }
        char id;
    };
    
    // In Java, I believe I could make something like this (not sure):
    
    public class A {
        public char id = 'A';
    }

    Salem, your idea is really good, thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wireless Network Linux & C Testbed
    By james457 in forum Networking/Device Communication
    Replies: 3
    Last Post: 06-11-2009, 11:03 AM
  2. sending structures through sockets
    By sunjayc99 in forum Networking/Device Communication
    Replies: 4
    Last Post: 07-01-2008, 07:43 PM
  3. Replies: 6
    Last Post: 06-11-2005, 04:10 AM
  4. Replies: 1
    Last Post: 08-01-2002, 08:26 PM
  5. Methods for Sorting Structures by Element...
    By Sebastiani in forum C Programming
    Replies: 9
    Last Post: 09-14-2001, 12:59 PM