473,395 Members | 1,460 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

pitfalls of struct to char* and back

I've got this homework assignment where I need to send some data over
a simulated network. Don't worry, I dont want someone to write the
code for me, just wondering if there are problems with the logic of my
solution.

The network API accepts a char* with a maximum of 40 bytes. I can
send and receive char* strings(under 40) all day long without
problem.
Then I created a struct of size 20 bytes:
struct RPCMsgType {
int transaction;

//client side
RPCMsgType rm;
strcpy(rm.name,"testLock");
rm.transaction = 9;
printf("size=%d\n",sizeof(rm));
char *RPCArray = (char*)&rm;
nc.sendMessage(0,0,RPCArray); //network client abstraction that does
a send to the rcvr

If I cast back to the struct on the client side, I have no problems.
However when it's received on server side and I try the same thing, I
get nonsense data:

//network receiver
postOffice->Receive(mbPort, &inPktHdr, &inMailHdr, buffer);
char *buffer = new char[sizeof(RPCMsgType)];
RPCMsgType *rm = (RPCMsgType*)buffer;
printf("Got \"%d\" from %d:%d\n",rm-
>transaction,inPktHdr.from,inMailHdr.from);
fflush(stdout);

This printf always prints some really large number for rm->transaction
when it should be 9.

Obviously there is a big unknown to you, the reader, since there is
this network simulation black box but I'm just wondering if you could
understand why this might be happening, say from personal experience
in a related field? Some of you may recognize the network API and
realize the it is from the NACHOS simulator.

Thanks for any insight, pointers, suggestions, etc...

-Kevin

Mar 14 '07 #1
5 1972

"kevincw01" <ke***@netkev.comwrote in message
news:11**********************@d57g2000hsg.googlegr oups.com...
I've got this homework assignment where I need to send some data over
a simulated network. Don't worry, I dont want someone to write the
code for me, just wondering if there are problems with the logic of my
solution.

The network API accepts a char* with a maximum of 40 bytes. I can
send and receive char* strings(under 40) all day long without
problem.
Then I created a struct of size 20 bytes:
struct RPCMsgType {
int transaction;

//client side
RPCMsgType rm;
strcpy(rm.name,"testLock");
rm.transaction = 9;
printf("size=%d\n",sizeof(rm));
char *RPCArray = (char*)&rm;
nc.sendMessage(0,0,RPCArray); //network client abstraction that does
a send to the rcvr
This call, I notice, does not receive the size of the data to send. So most
likely you are using strlen or such and determining the length by the
placement of the first null character. That will work for actual string
data, but not binary data. The size of an int is dependant on your machine,
lets go with an example of a machine with a int size of 4, that stores LSBF
(Least signifiacnt byte first).

Your value of 9 then is stored in 4 bytes, with the least significant byte
set to 9, the rest set to 0. (There could be other arrangments, we're just
using this as an example).

Now, the char* will point to the byte with the 9 in it. Your send will see
the 9 then a 0, so thinks that there is a data length of 1, when it is
actually 4. So it will send 1 byte.

The receiving end receives presumedly until it receives a null also, so it
receives 1 byte.

Now you try to take this data and put it back into an int. The least
significant byte will contain the 9. But what of the other 3 bytes? They
will contain... anything. Whatever happens to be in memory past the data.
Which is why it's showing you the value as some large number, random data.

What you need to do for your send is also pass the length of the data to
send, in this case sizeof rm.

Now, if you don't want to have to calculate the size for strings, just
binary data, then you can do something like, if I pass a 0, then I'll use
strlen to figure out the length, otherwise I"ll use the passed in length.
>
If I cast back to the struct on the client side, I have no problems.
However when it's received on server side and I try the same thing, I
get nonsense data:

//network receiver
postOffice->Receive(mbPort, &inPktHdr, &inMailHdr, buffer);
char *buffer = new char[sizeof(RPCMsgType)];
RPCMsgType *rm = (RPCMsgType*)buffer;
printf("Got \"%d\" from %d:%d\n",rm-
>>transaction,inPktHdr.from,inMailHdr.from);
fflush(stdout);

This printf always prints some really large number for rm->transaction
when it should be 9.

Obviously there is a big unknown to you, the reader, since there is
this network simulation black box but I'm just wondering if you could
understand why this might be happening, say from personal experience
in a related field? Some of you may recognize the network API and
realize the it is from the NACHOS simulator.

Thanks for any insight, pointers, suggestions, etc...

-Kevin

Mar 14 '07 #2
On 2007-03-14 09:20, kevincw01 wrote:
I've got this homework assignment where I need to send some data over
a simulated network. Don't worry, I dont want someone to write the
code for me, just wondering if there are problems with the logic of my
solution.

The network API accepts a char* with a maximum of 40 bytes. I can
send and receive char* strings(under 40) all day long without
problem.
Then I created a struct of size 20 bytes:
struct RPCMsgType {
int transaction;
I assume that the rest of the struct looks like this:
char name[16]; // Assuming 4 bytes for an int

Note that if you have char* name instead you'll get problems since the
string is not part of the struct, but I figure you'd noticed that when
you perform the strcpy() below.
>
//client side
RPCMsgType rm;
strcpy(rm.name,"testLock");
rm.transaction = 9;
printf("size=%d\n",sizeof(rm));
char *RPCArray = (char*)&rm;
nc.sendMessage(0,0,RPCArray); //network client abstraction that does
a send to the rcvr

If I cast back to the struct on the client side, I have no problems.
However when it's received on server side and I try the same thing, I
get nonsense data:

//network receiver
postOffice->Receive(mbPort, &inPktHdr, &inMailHdr, buffer);
char *buffer = new char[sizeof(RPCMsgType)];
Are you sure that you have not swapped the above two lines?
RPCMsgType *rm = (RPCMsgType*)buffer;
printf("Got \"%d\" from %d:%d\n",rm-
>>transaction,inPktHdr.from,inMailHdr.from);
fflush(stdout);
As Jim Langstom pointed out it might be a problem with using strlen when
sending the data, if it's you who wrote the sendMessage() method then I
would suggest that you rewrite it to accept a RPCMsgType instead of a
char* as argument, you could probably do the same for Receive().

--
Erik Wikström
Mar 14 '07 #3
//network receiver
postOffice->Receive(mbPort, &inPktHdr, &inMailHdr, buffer);
char *buffer = new char[sizeof(RPCMsgType)];

Are you sure that you have not swapped the above two lines?
Sorry, yes, the char memory allocation is before the receive.

I can't rewrite the network API but Jim is right. The strlen was
interpretting the size wrong(well right if it were a char string but
its not). I changed it to sizeof() and now it works! Thanks guys.
Mar 14 '07 #4
On Mar 14, 10:52 am, "kevincw01" <k...@netkev.comwrote:
//network receiver
postOffice->Receive(mbPort, &inPktHdr, &inMailHdr, buffer);
char *buffer = new char[sizeof(RPCMsgType)];
Are you sure that you have not swapped the above two lines?

Sorry, yes, the char memory allocation is before the receive.

I can't rewrite the network API but Jim is right. The strlen was
interpretting the size wrong(well right if it were a char string but
its not). I changed it to sizeof() and now it works! Thanks guys.
Woops, looks like its *almost working*. I can print out the int but
when I print the char[10] i only get the first letter. The struct got
cut off last time so here it is again:
struct RPCMsgType {
int transaction;
char name[10];
int lockID;
};

Mar 14 '07 #5
On 14 Mar, 21:14, "kevincw01" <k...@netkev.comwrote:
On Mar 14, 10:52 am, "kevincw01" <k...@netkev.comwrote:
//network receiver
postOffice->Receive(mbPort, &inPktHdr, &inMailHdr, buffer);
char *buffer = new char[sizeof(RPCMsgType)];
Are you sure that you have not swapped the above two lines?
Sorry, yes, the char memory allocation is before the receive.
I can't rewrite the network API but Jim is right. The strlen was
interpretting the size wrong(well right if it were a char string but
its not). I changed it to sizeof() and now it works! Thanks guys.

Woops, looks like its *almost working*. I can print out the int but
when I print the char[10] i only get the first letter. The struct got
cut off last time so here it is again:
struct RPCMsgType {
int transaction;
char name[10];
int lockID;

};
Since the size of RPCMsgType is fixed (18 bytes or so) I don't quite
see why you bother with the size, it is after all known. So send all
the bytes in the struct and expect to receive as many too.

PS, you can probably shrink the RPCMsgType to 18 bytes (if it's 20) by
putting the declaration of lockID above the declaration of transaction
since the compiler will probably place lockID on a 4-byte boundary,
which will be 2 bytes after the end of name.

--
Erik Wikström

Mar 15 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Angus Comber | last post by:
Hello I have received a lot of help on my little project here. Many thanks. I have a struct with a string and a long member. I have worked out how to qsort the struct on both members. I can...
10
by: Sean | last post by:
I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. ...
56
by: ccwork | last post by:
Hi all, Here is a sample code segment: .... typedef PACKED struct { union { PACKED struct { char red:1;
21
by: hermes_917 | last post by:
I want to use memcpy to copy the contents of one struct to another which is a superset of the original struct (the second struct has extra members at the end). I wrote a small program to test...
32
by: Weiguang Shi | last post by:
Hi, Is there a tool that, given a struct definition, generates a function that parses binary data of this struct and a command that can be used to construct binary data according to...
14
by: Lane Straatman | last post by:
I would like to write a 'struct'. I have a library that is all but completely inappropriate for this task. So I'm looking for C code that fills in the gaps between: #undef...
25
by: SRR | last post by:
Consider the following code: #include <stdio.h> #include <string.h> struct test{ char a; } funTest( void ); int main( void ) {
19
by: rmr531 | last post by:
First of all I am very new to c++ so please bear with me. I am trying to create a program that keeps an inventory of items. I am trying to use a struct to store a product name, purchase price,...
13
by: wexx | last post by:
Hello guys, Ok here is the issue/roadblock. I am trying to call a method that is a member of a c++ class. I know I need to have a wrapper function to give C a pointer to the member function. I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.