LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-19-2005, 07:49 PM   #1
alaios
Senior Member
 
Registered: Jan 2003
Location: Aachen
Distribution: Opensuse 11.2 (nice and steady)
Posts: 2,203

Rep: Reputation: 45
Unhappy 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
 
Old 09-19-2005, 07:54 PM   #2
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
try sizeof(mystructs)*10
 
Old 09-19-2005, 11:53 PM   #3
alaios
Senior Member
 
Registered: Jan 2003
Location: Aachen
Distribution: Opensuse 11.2 (nice and steady)
Posts: 2,203

Original Poster
Rep: Reputation: 45
I dont think this works... any new suggestion plz?
 
Old 09-20-2005, 12:26 AM   #4
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
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] ) */
 
Old 09-20-2005, 12:59 AM   #5
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
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
 
Old 09-20-2005, 01:48 AM   #6
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
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.
 
Old 09-20-2005, 06:23 AM   #7
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
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.
 
Old 04-11-2020, 11:47 PM   #8
barunparichha
Member
 
Registered: Jun 2006
Location: Bangalore,india
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 303

Rep: Reputation: 32
have you considered endianness of machine ?
sender x86 but receiver sparc type.
 
Old 04-12-2020, 05:37 AM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,879
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Either that, or the possibility of time-travel.
 
1 members found this post helpful.
Old 04-12-2020, 09:52 AM   #10
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
*****Drat Should have paid attention to NevemTeve's time travel comment

Quote:
Originally Posted by alaios View Post
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

Last edited by SoftSprocket; 04-12-2020 at 12:16 PM. Reason: Realizing the error of my ways!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
send/recv binary files with C++ sockets dafatdude Programming 3 02-12-2006 08:02 AM
how can i send a file using linux sockets?? crapodino Programming 2 10-09-2005 11:17 PM
Sockets: multiple send() calls throttle server framerate. JCipriani Programming 3 09-22-2005 07:06 PM
sockets dont ever send data alaios Programming 1 09-21-2005 06:59 PM
switch statement converting struct char to struct int oceaneyes2 Programming 2 12-10-2003 04:30 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:39 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration