Thread: C network newb

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    4

    C network newb

    Hello all, I am a newb at this so bare with me here....

    I have created a client/server program that communicate with each other. My goal is to compute the data rate of a link between two devices. The way I do this is by simply sending a message of some size to the other device (for now I am working with only two nodes) and computing the arrival times etc.

    I have a custom message struct that has variables for when the message is sent and received and some other required info. That's not important for now. All I want to know is, without modifying the contents of the struct, I want to send different size data with my custom messages for calculating the data rate. Basically, how can I increase the size/ append extra bytes to the message struct to be sent through a socket (currently using UDP socket)?

    For debugging purposes I simply created an empty char data[1024] and cast my message struct to the data:

    union my_message *msg;
    msg = (union my_message *) data;

    I sent it through the socket:

    sendto(socket, (char *)msg, 1024, ....);

    Apparently the sendto function is successful and returns 1024 bytes written even though the actual data (custom message struct) is less than 1024. The server side also correctly receives 1024 bytes. I always thought I had to fill the array with dummy data, is that required? or is it enough just to create the empty array, cast my filled up struct to it and send it?

    Thanks guys, just trying to wrap my head around this....
    Last edited by htpw16; 04-12-2009 at 01:53 AM.

  2. #2
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Apparently the sendto function is successful and returns 1024 bytes written even though the actual data (custom message struct) is less than 1024. The server side also correctly receives 1024 bytes. I always thought I had to fill the array with dummy data, is that required? or is it enough just to create the empty array, cast my filled up struct to it and send it?
    It's fine, the sendto function doesn't care about what you are sending, if it has been unitialized or not, as long as it can be read (i.e. the memory belongs to your process).

    But I wouldn't consider what you are doing as good programming practice. There's different way to "pad" a structure (in your case, padding an union is rather easy, just declare a "unsigned char [1024]" field) with either compiler specific directives or doing stuff like
    Code:
    #include <stdio.h>
    
    struct test
    {
        int a;
    };
    
    struct test_64
    {
        struct test t;
        unsigned char fill[64 - sizeof(struct test)];
    };
    
    int main()
    {
        struct test_64 t64;
        printf("sizeof(t64) = %u\n", sizeof(t64));
    
        return 0;
    }
    I hate real numbers.

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    4
    Thank you sir for your reply. One more question. So I followed your advice and added some padding to my struct:

    Code:
    struct pkt
    {
    my_message *msg;
    unsigned char fill[1024 - sizeof(my_message*)];
    };
    
    struct pkt p;
    so I proceed to populate the msg information in p:

    Code:
    p.msg->blabla;
    ...
    now when I use the sendto function:

    Code:
    sendto(socket, (char *)&p, sizeof(p), ....);
    How can the server receive this information? Currently, in short, the server side looks like this:

    Code:
    char buf[1024];
    struct pkt p;
    recv(socket, buf, sizeof(buf), 0);
    p = (struct pkt*) buf;
    That doesn't seem to work. How can I cast this received information to my struct pkt?

    Thank you.
    Last edited by htpw16; 04-12-2009 at 06:47 PM.

  4. #4
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    I might have talked too soon. Actually, it looks like compilers doesn't support the kind of padding I was talking.

    Anyway. In your case, you would be better with an union instead of a struct. Simpler.
    Code:
    union pkt
    {
        my_message msg;
        unsigned char fill[1024];   // Magic numbers aren't good programming practice neither :)
    };
    Now, "union pkt" variables will always be at least 1024 bytes. Then, you would use the sendto function like this
    Code:
    union pkt p;
    sendto(socket, (char *) &p, sizeof(union pkt), ...);
    and recv like this
    Code:
    union pkt p;
    recv(socket, (char *) &p, ...);
    Anyway, there's different way to do it (another would be to copy the content of your "my_message" variables into a 1024 bytes buffer before sending it) and it's mostly a question about how you want your code to look. The way you described is the more "hackish". The "union padding" is the more space inefficient. The "copy before sending" is the less time efficient, even if it would be neglible.

    But then, if you want your program to be portable (i.e. you want to run it on different architecture), you might have to serialize your "my_message" variables before sending them. And this is another subject...

    If your devices are running Linux, you can easily check the link speed with simple commands, if you want to save some time on writing a program.
    I hate real numbers.

  5. #5
    Registered User
    Join Date
    Apr 2009
    Posts
    4
    Thank you for your help...one problem though:

    On the server side it seems as though the pkt p is full of garbage since my program prints out incorrect info for the msg part of p, such as all zeros etc..:

    Code:
    printf("Packet size = %i", p.msg->pkt_size);
    Finally got this to work. Thanks for your help.
    Last edited by htpw16; 04-13-2009 at 01:26 AM. Reason: Problem solved

  6. #6
    Registered User
    Join Date
    Apr 2009
    Posts
    4
    Quote Originally Posted by foxman View Post
    It's fine, the sendto function doesn't care about what you are sending, if it has been unitialized or not, as long as it can be read (i.e. the memory belongs to your process).
    But wouldn't the sendto function error out if there is no actual data to be sent. Since in my case it didn't does that mean sendto was sending empty bytes once all the msg data was sent? If thats the case are empty bytes the same as actual data since I am calculating the throughput and it needs to be accurate. Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 3D Network Analysis Tool
    By durban in forum Projects and Job Recruitment
    Replies: 1
    Last Post: 11-08-2005, 06:33 PM
  2. Need help with easy Network setup
    By the dead tree in forum Tech Board
    Replies: 9
    Last Post: 04-08-2005, 07:44 PM
  3. network problems
    By lucy in forum Tech Board
    Replies: 6
    Last Post: 01-01-2003, 03:33 PM
  4. network programming
    By threahdead in forum C Programming
    Replies: 1
    Last Post: 10-27-2002, 04:15 PM
  5. WinXP Network Connections pop-up
    By DavidP in forum Tech Board
    Replies: 1
    Last Post: 10-02-2002, 05:36 PM