LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   cant send a whole struct with sockets (c code) (https://www.linuxquestions.org/questions/programming-9/cant-send-a-whole-struct-with-sockets-c-code-365050/)

alaios 09-19-2005 07:49 PM

cant send a whole struct with sockets (c code)
 
Hi all!! Thats a new problem that i have discovered..
I have an array of structs and i want to pass them to the other pc

struct {
field
field
field
}mystructs[10];



if (sendto(sock,mystructs,sizeof(mystructs[10]), 0,(struct sockaddr 1*) &server, server_len) <0){


the other pc receives that
if ((n=recvfrom(sock,&mystructs,sizeod(mystructs[0]),0, mpla mpla mpla.....

I have spent a whole night changing and trying the following parameters
mystructs instead of &mystructs
sizeof(mystructs)
sizeof(mystructs[10])
sizeof(mystructs[0])

all these methods have the same results.. to pass only the first struct of the array which is the mystructs[0]... all the others mystruct[1] mystructs[2] are null..
Plz guys help me its an emergency

jlliagre 09-19-2005 07:54 PM

try sizeof(mystructs)*10

alaios 09-19-2005 11:53 PM

I dont think this works... any new suggestion plz?

addy86 09-20-2005 12:26 AM

Quote:

Originally posted by alaios
I dont think this works... any new suggestion plz?
You don't think it works or you know it doesn't work?

Have you initialized mystructs[1] to [9]?

Try to declare a type (no direct definition):
struct mystruct_s {
field
field
field
};

struct mystruct_s mystructs[10];

Then use the following:
&mystructs[0]
sizeof(mystructs) /* Or alternatively: sizeof( mystruct_s[10] ) */

paulsm4 09-20-2005 12:59 AM

Please re-read post #5 in this thread:

http://www.linuxquestions.org/questi...hreadid=363900

Forget about the "real" program you're trying to develop, forget about "sockets" and "passing data to the other PC" for a moment.

The issues you need to deal with are:
"what is a struct?"
"what is an array?"
"how are they represented in memory?"
"how do I access (or pass to some other function) just that one piece of a complex structure I really mean to access?"
... and ..
"am I actually accessing (or passing) the piece I *think* I'm accessing?"

Basic stuff ... but crucial.

Your .. PSM

jlliagre 09-20-2005 01:48 AM

Quote:

I dont think this works... any new suggestion plz?
In fact, one correct answer is "sizeof(mystructs)" and was working on the first place, your problem is elsewhere as previous replies states.

Hivemind 09-20-2005 06:23 AM

I've never used recvfrom() and sendto(), only send() and recv() but this code (not complete could use more robust error detection and displaying) works for me:

Test struct declaration:
Code:

#ifndef GLOBALS_H
#define GLOBALS_H

/* An instance of this struct will be sent and displayed on the receiving end. */
struct test_struct_t
{
char buffer[32];
int n;
};

#endif /* #ifndef GLOBALS_H */

Code for connecting and sending:
Code:

static void
connect_and_send()
{
  int sock_fd = 0;
  struct hostent* server = NULL;
  struct sockaddr_in server_address;
  struct test_struct_t test_struct;
  socklen_t socklen = sizeof(struct sockaddr_in);

  /* Zero out struct instances before we use them */
  memset(&server_address, 0, sizeof(struct sockaddr_in));
  memset(&test_struct, 0, sizeof(struct test_struct_t));
 
  sock_fd = socket(AF_INET, SOCK_STREAM, 0);

  assert(sock_fd != -1);

  server = gethostbyname("localhost");

  assert(server); 

  server_address.sin_family = AF_INET;
  server_address.sin_port = htons(4711);
  memcpy(&server_address.sin_addr.s_addr, server->h_addr, server->h_length);
 
  errno = 0;
 
  if(connect(sock_fd, (struct sockaddr*)&server_address,
              sizeof(server_address)) == -1)
  {
      fprintf(stderr, "connect() failed.\n");
      fprintf(stderr, "Error description: %s\n", strerror(errno));
     
      return;
  }

  test_struct.n = 1337;
  strcpy(test_struct.buffer, "Hello!");

  errno = 0;
 
  if(sendto(sock_fd, (const void *)&test_struct, sizeof(struct test_struct_t), 0,
            (struct sockaddr *)&server_address, socklen) == -1)
  {
      fprintf(stderr, "send() failed.\n");
      fprintf(stderr, "Error description: %s\n", strerror(errno));

      return;
  }
}

Code for receiving and displaying:
Code:

void
receive_and_display(void)
{
  int server_socket = 0;
  int connected_client = 0;
  struct sockaddr_in client_address;
  struct test_struct_t test_struct;
  socklen_t socklen = sizeof(struct sockaddr_in);

  /* Zero out struct instances before we use them */
  memset(&client_address, 0, sizeof(struct sockaddr_in));
  memset(&test_struct, 0, sizeof(struct test_struct_t));
 
  connected_client = wait_for_connection(&server_socket, &client_address);

  if(connected_client == -1)
      fprintf(stderr, "wait_for_connection() failed.\n");
 
    if(recvfrom(connected_client, (void *)&test_struct, sizeof(struct test_struct_t),
              0, (struct sockaddr *)&client_address, &socklen) == -1)
      fprintf(stderr, "recvfrom() failed.\n");
  else
  {
      printf("test_struct.buffer = %s\n", test_struct.buffer);
      printf("test_struct.n = %i\n", test_struct.n);
  }
}

static int
wait_for_connection(int *server_socket, struct sockaddr_in *client_address)
{
  struct sockaddr_in server_address;
  socklen_t socklen = sizeof(struct sockaddr_in);

  memset(&server_address, 0, socklen);

  server_address.sin_family = AF_INET;
  server_address.sin_addr.s_addr = INADDR_ANY;
  server_address.sin_port = htons(4711);

  *server_socket = socket(AF_INET, SOCK_STREAM, 0);

  if(*server_socket == -1)
      return -1;

  if(bind(*server_socket, (struct sockaddr*)&server_address, socklen) == -1)
      return -1; /* TODO: Print error message. */

  if(listen(*server_socket, 0) == -1)
      return -1; /* TODO: Print error message. */

  return accept(*server_socket, (struct sockaddr *)&client_address, &socklen);
}

This works fine for me.

barunparichha 04-11-2020 11:47 PM

have you considered endianness of machine ?
sender x86 but receiver sparc type.

NevemTeve 04-12-2020 05:37 AM

Either that, or the possibility of time-travel.

SoftSprocket 04-12-2020 09:52 AM

*****Drat Should have paid attention to NevemTeve's time travel comment

Quote:

Originally Posted by alaios (Post 1860982)
Hi all!! Thats a new problem that i have discovered..
I have an array of structs and i want to pass them to the other pc

struct {
field
field
field
}mystructs[10];



if (sendto(sock,mystructs,sizeof(mystructs[10]), 0,(struct sockaddr 1*) &server, server_len) <0){


the other pc receives that
if ((n=recvfrom(sock,&mystructs,sizeod(mystructs[0]),0, mpla mpla mpla.....

I have spent a whole night changing and trying the following parameters
mystructs instead of &mystructs
sizeof(mystructs)
sizeof(mystructs[10])
sizeof(mystructs[0])

all these methods have the same results.. to pass only the first struct of the array which is the mystructs[0]... all the others mystruct[1] mystructs[2] are null..
Plz guys help me its an emergency

Well, since it's an emergency... :)

Although you haven't posted any code there is a lot of confusion being expressed. I've always found that in C, and really any programming language, it is best to both test concepts, and read, how things are supposed to work. I've posted a small sample program if you compile and run it you'll we see possible issues expressed with how you are approaching this. I've posted my output, as well as the output from compiling it.

Things to note. First that sizeof for a struct isn't necessarily the same as the size of its aggregate parts. In fact, in some instances, the compiler is padding the struct with extra bytes in the interest of alignment; and it can be different on a different machine or with a different compiler.

If you look at the output from my compiler you will see a lot of warnings. Essentially they are saying that sizeof, in the function call, may not be doing what the programmer thinks it is doing.

The reason I bring these things up is that for a program to act as expected there are things that have to be understood. Sending a struct over a socket may work under some conditions but won't under others. It's a better idea to serialize a struct before sending it over a tream - i.e. send the individual fields - and deserialize at the other end.

You might benefit from spending some time considering what an array of structs is and how you refer to a single element (and its size) vs the array (and its size) - where it's being passed to a function and where it's not.

Personally I write a lot of test programs to help me understand how some piece of code will perform. This lets me get one part right without the confusion of a complicated program. This is also a good practice when asking for help. Post the smallest program you can devise that demonstrates your problem or confusion.

Code:

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

struct data {
        int a;
        int b;
        int c;
};

struct data2 {
        int a;
        char b;
        long c;
};

struct data3 {
        int a;
        long b;
        char s[20];
};


void test_function (struct data data_array[10], struct data2 data2_array[10], struct data3 data3_array[10]) {
        printf ("\n\nsizeof struct data = %lu\n", sizeof (struct data));
        printf ("sizeof int + int + int = %lu\n", sizeof (int) + sizeof (int) + sizeof (int));
        printf ("sizeof  data_array = %lu\n", sizeof data_array);

        printf ("sizeof struct data2 = %lu\n", sizeof (struct data2));
        printf ("sizeof int + char + long = %lu\n", sizeof (int) + sizeof (char) + sizeof (long));
        printf ("sizeof  data2_array = %lu\n", sizeof data2_array);

        printf ("sizeof struct data3 = %lu\n", sizeof (struct data3));
        printf ("sizeof int + long + char[20] = %lu\n", sizeof (int) + sizeof (long) + (sizeof (char) * 20));
        printf ("sizeof  data3_array = %lu\n", sizeof data3_array);
}

int main () {
        struct data data_array[10];
        struct data2 data2_array[10];
        struct data3 data3_array[10];

        printf ("sizeof struct data = %lu\n", sizeof (struct data));
        printf ("sizeof int + int + int = %lu\n", sizeof (int) + sizeof (int) + sizeof (int));
        printf ("sizeof  data_array = %lu\n", sizeof data_array);

        printf ("sizeof struct data2 = %lu\n", sizeof (struct data2));
        printf ("sizeof int + char + long = %lu\n", sizeof (int) + sizeof (char) + sizeof (long));
        printf ("sizeof  data2_array = %lu\n", sizeof data2_array);

        printf ("sizeof struct data3 = %lu\n", sizeof (struct data3));
        printf ("sizeof int + long + char[20] = %lu\n", sizeof (int) + sizeof (long) + (sizeof (char) * 20));
        printf ("sizeof  data3_array = %lu\n", sizeof data3_array);

        test_function (data_array, data2_array, data3_array);

        return 0;
}

My output:
Code:

sizeof struct data = 12
sizeof int + int + int = 12
sizeof  data_array = 120
sizeof struct data2 = 16
sizeof int + char + long = 13
sizeof  data2_array = 160
sizeof struct data3 = 40
sizeof int + long + char[20] = 32
sizeof  data3_array = 400


sizeof struct data = 12
sizeof int + int + int = 12
sizeof  data_array = 8
sizeof struct data2 = 16
sizeof int + char + long = 13
sizeof  data2_array = 8
sizeof struct data3 = 40
sizeof int + long + char[20] = 32
sizeof  data3_array = 8

Compiler ouput:

Code:

$ gcc -Wall array_of_structs.c -o array_of_structs
array_of_structs.c: In function ‘test_function’:
array_of_structs.c:26:47: warning: ‘sizeof’ on array function parameter ‘data_array’ will return size of ‘struct data *’ [-Wsizeof-array-argument]
  printf ("sizeof  data_array = %lu\n", sizeof data_array);
                                              ^
array_of_structs.c:23:33: note: declared here
 void test_function (struct data data_array[10], struct data2 data2_array[10], s
                                ^
array_of_structs.c:30:48: warning: ‘sizeof’ on array function parameter ‘data2_array’ will return size of ‘struct data2 *’ [-Wsizeof-array-argument]
  printf ("sizeof  data2_array = %lu\n", sizeof data2_array);
                                                ^
array_of_structs.c:23:62: note: declared here
 void test_function (struct data data_array[10], struct data2 data2_array[10], s
                                                              ^
array_of_structs.c:34:48: warning: ‘sizeof’ on array function parameter ‘data3_array’ will return size of ‘struct data3 *’ [-Wsizeof-array-argument]
  printf ("sizeof  data3_array = %lu\n", sizeof data3_array);
                                                ^
array_of_structs.c:23:92: note: declared here
 uct data data_array[10], struct data2 data2_array[10], struct data3 data3_array



All times are GMT -5. The time now is 02:20 PM.