Networking Forums

Networking Forums > Computer Networking > Linux Networking > Plz Help ..Strucs-->U_char arrays<--Structs

Reply
Thread Tools Display Modes

Plz Help ..Strucs-->U_char arrays<--Structs

 
 
ANaiveProgrammer
Guest
Posts: n/a

 
      12-07-2004, 09:17 AM
Hi all
I have been trying to send a struct over socket. I tried to assign the
values of struct
to unsigned char array. I have attached both .c files at the bottom.
'Client.c' takes a
struct, arrange the struct in u_char array and send the u_char array
to 'Server.c'. Now
'Server.c' takes the u_char array and assign to the struct and
displays its values.
Now im totally stumped and im facing following problems though i have
tried to locate errors
thoroughly , but im unable to understand what is the problem

a-)I am not sure about usage of 'memcpy'. My struct contains two
u_int's and one char array of 5
elements.Now im doing the following to assign my struct elements to
u_char array in 'parse_struct'
function in 'Client.c' file

memcpy(off,(void *)&(s->a),sizeof(s->a));
off += sizeof(s->a);
memcpy(off,(void *)&(s->b),sizeof(s->b));
off += sizeof(s->b);
/*
Now im really stumped about the following, is it correct? I think
it should work because 'memcpy' needs addresses of elements to be
copied and
the number of bytes and i think '&s->name' will assign the string
'hello'
to off, but plz correct me if im wrong....
*/
memcpy(off,(void *)&s->name,sizeof(s->name));

b-)Now in 'Server.c' file im using memcpy as follows
memcpy( &(dest->a), off, sizeof(dest->a));
off += sizeof(dest->a);
memcpy(&(dest->b),off,sizeof(dest->b));
off += sizeof(dest->b);
//Again , to me, following line is Ok
memcpy((char *)&(dest->name),off,sizeof(dest->name));
because as memcpy returns a pointer to destination and my
following check successfuly returns the correct value of
'Hello' after the execution of following 'while' loop

char *ptr;
memcpy(&(dest->b),off,sizeof(dest->b));
off += sizeof(dest->b);
ptr = (unsigned char *)memcpy((char
*)&(dest->name),off,sizeof(dest->name));
printf("butt_to_struct()--ptr(dest-->name)...\n");
while( *ptr != 'o' )
printf("%c",*ptr++);
printf("%c\n",*ptr);

c-)Now to execute my task , i run 'Server.c' first and then 'Client.c'
from other
terminal. Now for the first time program runs fine. Then i terminate
both 'Server.c'
and 'Client.c' programs and when i run these two files again without
ever changing them
then 'Client.c' does execute but after the execution it prints 'Pipe
Broken' and exits. Now
Though 'Client.c' has executed but when i switch my terminal to see
whts going in 'Server.c' program
it is still waiting for a connection.
I mean this is absurd, why the heck program i.e 'Client.c' tells me
'Broken Pipe'
when being executed for the second time? This is beyond my
comprehension

d-) Last but not the least , in the main() of 'Server.c' when i
successfully
return from buff_to_struct() function and try to do the following
printf("Value of name = %s\n",s.name);
it prints
HelloBx
though it should have printed only 'Hello', now where these last two
bytes i.e. 'Bx'
came from ?
I know this must be time consuming for you, but im really stumped
about this so
i will really appreciate any kind of help. Thanks a lot for your
concern & time.....
Thanks in anticipation.

Regards....

Both 'Server.c' And 'Client.c' are attached below & im using gcc over
Red hat linux 8.0

Server.c
-----------
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>

typedef struct{
uint8_t a;
uint8_t b;
char name[5];
}str;

void buff_to_struct(str *dest, unsigned char *src){


unsigned char *off;
int len;
len =0;
off = src;


memcpy( &(dest->a), off, sizeof(dest->a));

off += sizeof(dest->a);
char *ptr;

memcpy(&(dest->b),off,sizeof(dest->b));
off += sizeof(dest->b);
ptr = (unsigned char *)memcpy((char
*)&(dest->name),off,sizeof(dest->name));
printf("butt_to_struct()--ptr(dest-->name)...\n");
while( *ptr != 'o' )
printf("%c",*ptr++);
printf("%c\n",*ptr);




}
int main()

{
str s;
int fd;
printf("Size of str--ptr..%d\n",sizeof(str));
struct sockaddr_in server,client;

fd = socket(AF_INET,SOCK_STREAM,0);
server.sin_family = AF_INET;
server.sin_port =htons(1800);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(fd, (struct sockaddr *)&server,sizeof(server));
listen(fd,2);
printf("Listening to Connetions...\n");

int len;
len = sizeof(client);
int connfd;
connfd = accept(fd, (struct sockaddr*)&client, &len);

unsigned char src[7];
int readlen ;
read(connfd,src,7);


buff_to_struct(&s,src);


printf("Value received(s.a)---=%d\n",s.a);
printf("Value of s.b =%d\n",s.b);
//Problem lies in the following, it *must* print 'Hello' but following
//line prints 'HelloBx' , why??????
printf("Value of name = %s\n",s.name);
printf("\n");

close(fd);
return 0;
}









__________________________________________________ ______________________________________
Client.c
---------
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

typedef struct{
uint8_t a;
uint8_t b;
char name[5];

}str;

int parse_struct(unsigned char *dest,str *s){

unsigned char *off;
off = dest;

memcpy(off,(void *)&(s->a),sizeof(s->a));

off += sizeof(s->a);
memcpy(off,(void *)&(s->b),sizeof(s->b));

off += sizeof(s->b);
char *ptr;

ptr = (char *)memcpy(off,(void *)&s->name,sizeof(s->name));
//Purpose of following 'while' is to check the contents of 'off'
while (*ptr !='o')
printf("%c",*ptr++);
printf("%c\n",*ptr);
//Aforementioned while correctly prints the value of 'ptr'
printf("(Parse_struct) off=%s\n",off);

off += sizeof(s->name);
char ch='\0';
memcpy(off,(void *)& ch, sizeof(ch));

int len ;
len = sizeof(s->a)+sizeof(s->b)+sizeof(s->name);
return len;

}
int main(){

str s;
s.a = 10;
s.b = 20;
strcpy(s.name,"Hello");


int fd;
struct sockaddr_in client;
fd = socket(AF_INET,SOCK_STREAM,0);
client.sin_family = AF_INET;
client.sin_port = htons(1800);
client.sin_addr.s_addr = inet_addr("127.0.0.1");



connect(fd,(struct sockaddr*)&client,sizeof(client));


printf("Connected and Writing data...\n");

unsigned char buff[7];
int len;
len = parse_struct(buff,&s);

write(fd,buff,len);


exit(0);

}
 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?Bj=F8rn_Augestad?=
Guest
Posts: n/a

 
      12-07-2004, 03:46 PM
ANaiveProgrammer wrote:
[Lots of stuff snipped]

>
> typedef struct{
> uint8_t a;
> uint8_t b;
> char name[5];
>
> }str;
>

[snip]

> strcpy(s.name,"Hello");


Here's at least one error. You strcpy() 6 bytes into a 5 byte array. The
rest looked more or less ok, but you can drop lots of casts to void*.

HTH
Bjørn

[snip]
 
Reply With Quote
 
Larry I Smith
Guest
Posts: n/a

 
      12-07-2004, 03:55 PM
ANaiveProgrammer wrote:
> Hi all
> I have been trying to send a struct over socket. I tried to assign the
> values of struct
> to unsigned char array. I have attached both .c files at the bottom.
> 'Client.c' takes a
> struct, arrange the struct in u_char array and send the u_char array
> to 'Server.c'. Now
> 'Server.c' takes the u_char array and assign to the struct and
> displays its values.
> Now im totally stumped and im facing following problems though i have
> tried to locate errors
> thoroughly , but im unable to understand what is the problem
>
> a-)I am not sure about usage of 'memcpy'. My struct contains two
> u_int's and one char array of 5
> elements.Now im doing the following to assign my struct elements to
> u_char array in 'parse_struct'
> function in 'Client.c' file
>
> memcpy(off,(void *)&(s->a),sizeof(s->a));
> off += sizeof(s->a);
> memcpy(off,(void *)&(s->b),sizeof(s->b));
> off += sizeof(s->b);
> /*
> Now im really stumped about the following, is it correct? I think
> it should work because 'memcpy' needs addresses of elements to be
> copied and
> the number of bytes and i think '&s->name' will assign the string
> 'hello'
> to off, but plz correct me if im wrong....
> */
> memcpy(off,(void *)&s->name,sizeof(s->name));
>
> b-)Now in 'Server.c' file im using memcpy as follows
> memcpy( &(dest->a), off, sizeof(dest->a));
> off += sizeof(dest->a);
> memcpy(&(dest->b),off,sizeof(dest->b));
> off += sizeof(dest->b);
> //Again , to me, following line is Ok
> memcpy((char *)&(dest->name),off,sizeof(dest->name));
> because as memcpy returns a pointer to destination and my
> following check successfuly returns the correct value of
> 'Hello' after the execution of following 'while' loop
>
> char *ptr;
> memcpy(&(dest->b),off,sizeof(dest->b));
> off += sizeof(dest->b);
> ptr = (unsigned char *)memcpy((char
> *)&(dest->name),off,sizeof(dest->name));
> printf("butt_to_struct()--ptr(dest-->name)...\n");
> while( *ptr != 'o' )
> printf("%c",*ptr++);
> printf("%c\n",*ptr);
>
> c-)Now to execute my task , i run 'Server.c' first and then 'Client.c'
> from other
> terminal. Now for the first time program runs fine. Then i terminate
> both 'Server.c'
> and 'Client.c' programs and when i run these two files again without
> ever changing them
> then 'Client.c' does execute but after the execution it prints 'Pipe
> Broken' and exits. Now
> Though 'Client.c' has executed but when i switch my terminal to see
> whts going in 'Server.c' program
> it is still waiting for a connection.
> I mean this is absurd, why the heck program i.e 'Client.c' tells me
> 'Broken Pipe'
> when being executed for the second time? This is beyond my
> comprehension
>
> d-) Last but not the least , in the main() of 'Server.c' when i
> successfully
> return from buff_to_struct() function and try to do the following
> printf("Value of name = %s\n",s.name);
> it prints
> HelloBx
> though it should have printed only 'Hello', now where these last two
> bytes i.e. 'Bx'
> came from ?
> I know this must be time consuming for you, but im really stumped
> about this so
> i will really appreciate any kind of help. Thanks a lot for your
> concern & time.....
> Thanks in anticipation.
>
> Regards....


There are many problems with these 2 programs, but see
my comments embedded in the following source code for
answers regarding your immediate questions....


>
> Both 'Server.c' And 'Client.c' are attached below & im using gcc over
> Red hat linux 8.0
>
> Server.c
> -----------
> #include <sys/types.h>
> #include <string.h>
> #include <netinet/in.h>
> #include <sys/socket.h>
>
> typedef struct{
> uint8_t a;
> uint8_t b;
> char name[5];
> }str;
>
> void buff_to_struct(str *dest, unsigned char *src){
>
>
> unsigned char *off;
> int len;
> len =0;
> off = src;
>
>
> memcpy( &(dest->a), off, sizeof(dest->a));
>
> off += sizeof(dest->a);
> char *ptr;
>
> memcpy(&(dest->b),off,sizeof(dest->b));
> off += sizeof(dest->b);
> ptr = (unsigned char *)memcpy((char
> *)&(dest->name),off,sizeof(dest->name));
> printf("butt_to_struct()--ptr(dest-->name)...\n");
> while( *ptr != 'o' )
> printf("%c",*ptr++);
> printf("%c\n",*ptr);
>
>
>
>
> }
> int main()
>
> {
> str s;
> int fd;
> printf("Size of str--ptr..%d\n",sizeof(str));
> struct sockaddr_in server,client;
>
> fd = socket(AF_INET,SOCK_STREAM,0);
> server.sin_family = AF_INET;
> server.sin_port =htons(1800);
> server.sin_addr.s_addr = inet_addr("127.0.0.1");
> bind(fd, (struct sockaddr *)&server,sizeof(server));
> listen(fd,2);
> printf("Listening to Connetions...\n");
>
> int len;
> len = sizeof(client);
> int connfd;
> connfd = accept(fd, (struct sockaddr*)&client, &len);
>
> unsigned char src[7];
> int readlen ;
> read(connfd,src,7);
>
>
> buff_to_struct(&s,src);
>
>
> printf("Value received(s.a)---=%d\n",s.a);
> printf("Value of s.b =%d\n",s.b);
> //Problem lies in the following, it *must* print 'Hello' but following
> //line prints 'HelloBx' , why??????


Because the "%s" in the printf() format string tells printf() to
print a nul-terminated string, but s.name is NOT nul-terminated.
s.name[] is 5 bytes in size and contains 'h', 'e', 'l', 'l', 'o'.
This is NOT a nul-terminated string - there is no trailing '\0'.
Either use "%5.5s" in the printf() format string, or change the size
of 'name' in the definition of 'str' to be 6 bytes and then ALWAYS
write a nul byte to name[5] AS THE LAST WRITE operation before sending
it (e.g. copy bytes to 'name', THEN write a '\0' to name[5]).

> printf("Value of name = %s\n",s.name);
> printf("\n");
>
> close(fd);
> return 0;
> }
>
>
>
>
>
>
>
>
>
> __________________________________________________ ______________________________________
> Client.c
> ---------
> #include <string.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
>
> typedef struct{
> uint8_t a;
> uint8_t b;
> char name[5];
>
> }str;
>
> int parse_struct(unsigned char *dest,str *s){
>
> unsigned char *off;
> off = dest;
>
> memcpy(off,(void *)&(s->a),sizeof(s->a));
>
> off += sizeof(s->a);
> memcpy(off,(void *)&(s->b),sizeof(s->b));
>
> off += sizeof(s->b);
> char *ptr;
>
> ptr = (char *)memcpy(off,(void *)&s->name,sizeof(s->name));
> //Purpose of following 'while' is to check the contents of 'off'
> while (*ptr !='o')
> printf("%c",*ptr++);
> printf("%c\n",*ptr);
> //Aforementioned while correctly prints the value of 'ptr'
> printf("(Parse_struct) off=%s\n",off);
>
> off += sizeof(s->name);
> char ch='\0';
> memcpy(off,(void *)& ch, sizeof(ch));


The above memcpy() writes the nul byte (ch) PAST THE END
of dest[] (i.e. to dest[7], which is the 8th byte in dest[],
but dest[] IS ONLY 7 BYTES LONG). You're lucky that it
doesn't overwrite something important.
So, when main() writes dest[] (aka buff[] in main) to the
socket, the nul byte (ch) is NOT written - because it's
not in buff[].
If 's' has 7 bytes of data, and you wish to follow it with
a nul byte when it is copied to dest[], then dest[] must be
at least one byte larger (i.e. dest[] must be 8 bytes)

>
> int len ;
> len = sizeof(s->a)+sizeof(s->b)+sizeof(s->name);
> return len;
>
> }
> int main(){
>
> str s;
> s.a = 10;
> s.b = 20;
> strcpy(s.name,"Hello");
>
>
> int fd;
> struct sockaddr_in client;
> fd = socket(AF_INET,SOCK_STREAM,0);
> client.sin_family = AF_INET;
> client.sin_port = htons(1800);
> client.sin_addr.s_addr = inet_addr("127.0.0.1");
>
>
>
> connect(fd,(struct sockaddr*)&client,sizeof(client));
>
>
> printf("Connected and Writing data...\n");
>
> unsigned char buff[7];


The above should be 'unsigned char buff[8];'.

> int len;
> len = parse_struct(buff,&s);
>
> write(fd,buff,len);
>
>
> exit(0);
>
> }


Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




1 2 3 4 5 6 7 8 9 10 11