For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > August 2006 > struct over tcp socket









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author struct over tcp socket
ibaloubi

2006-08-15, 8:01 am

I'm putting a struct over a tcp socket. This works fine when doing it on the
loopback interface, however doing it over the internet it fails, the text
strings are correctly transmitted, while integers are not. What is the
might be the reason for this?
ibaloubi

2006-08-15, 8:01 am

ibaloubi wrote:

> I'm putting a struct over a tcp socket. This works fine when doing it on
> the loopback interface, however doing it over the internet it fails, the
> text strings are correctly transmitted, while integers are not. What is
> the might be the reason for this?

I forgot, the struct is:
struct HostInfo
{
enum {ONLINE=0x0001, OFFLINE=0x0002};
char m_Host[HOSTMAX];
unsigned int m_iState;
};
( the m_iState is zero when returned ) clue?
Pascal Bourguignon

2006-08-15, 8:01 am

ibaloubi <bobofibodibo@aaakyars.com> writes:

> ibaloubi wrote:
>
> I forgot, the struct is:
> struct HostInfo
> {
> enum {ONLINE=0x0001, OFFLINE=0x0002};
> char m_Host[HOSTMAX];
> unsigned int m_iState;
> };
> ( the m_iState is zero when returned ) clue?


Have you ever head of bytesex?
little endian, big endian?

--
__Pascal Bourguignon__ http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
ibaloubi

2006-08-15, 8:01 am

Pascal Bourguignon wrote:

> ibaloubi <bobofibodibo@aaakyars.com> writes:
>
>
> Have you ever head of bytesex?
> little endian, big endian?
>

yes, I have, but I don't know how to use the ntohl et al functions
when sending, should I use htonl, and when receiving convert using ntohl?
Nils O. Selåsdal

2006-08-15, 8:01 am

ibaloubi wrote:
> Pascal Bourguignon wrote:
>
> yes, I have, but I don't know how to use the ntohl et al functions
> when sending, should I use htonl, and when receiving convert using ntohl?

When sending a struct directly this way, you're sending the internal
representation as generated by your compiler. If it's received on
another host that isn't compatible with the sending host, it won't
be able to interpret the struct as you intended.

You're likely better off defining a protocol yourself, and not relying
on the internal represenation of C structs.

In addition, bear in mind that TCP is a stream, you are not guaranteed
that one write call results in just one recv call on the other end (or
vice verca)
ibaloubi

2006-08-15, 8:01 am

"Nils O. Selåsdal" wrote:

> ibaloubi wrote:
> When sending a struct directly this way, you're sending the internal
> representation as generated by your compiler. If it's received on
> another host that isn't compatible with the sending host, it won't
> be able to interpret the struct as you intended.
>
> You're likely better off defining a protocol yourself, and not relying
> on the internal represenation of C structs.
>
> In addition, bear in mind that TCP is a stream, you are not guaranteed
> that one write call results in just one recv call on the other end (or
> vice verca)

hmm, blast,
thank's Nils for that info.

Pascal Bourguignon

2006-08-15, 7:00 pm

ibaloubi <bobofibodibo@aaakyars.com> writes:

> "Nils O. Selåsdal" wrote:
>
> hmm, blast,
> thank's Nils for that info.


Indeed, on different processors, or even on the same processor, with a
different compiler the same C structure declaration can be compiled
with different offsets.


The best class of protocols are the ASCII based one.

1- ASCII = Americal Standard Code for INFORMATION INTERCHANGE.

2- Using a line-based ASCII protocol allows you to debug it easily
using telnet.

3- Often, ASCII data will be smaller than the equivalent binary
data. Yes, it's surprizing, but it's true. For strings, you'll get
the same size, +/- 1; for integers, you have a lot of usual
integers that need less than 4 bytes to be written in ASCII (1099
exactly).



So, you could send the structure:[color=darkred]
with:

struct HostInfo* hi;
fprintf(socket,"(HOSTINFO \"%s\" %d)\n",hi->m_Host,hi->m_iState);


and you can read it with:

if('('==fgets(socket)){
char type[64];
fscanf(socket,"[^ ]",&type);
if(strcmp(type,"HOSTINFO")==0){
char name[HOSTMAX];
unsigned int state;
fscanf(socket,"\"[^\"]\"",&name);
fscanf(socket,"%d",&state);
fscanf(socket,")");
{
struct HostInfo* hi=malloc(sizeof(struct HostInfo));
hi->m_Host=newstr(name);
hi->m_iState=state;
return(hi); }}
else{
error("Unknown type");}}
else{
error("syntax error");
}

for example.



Then you can easily test it:

telnet localhost $port
(HOSTINFO "Name" 1)
^]quit


--
__Pascal Bourguignon__ http://www.informatimago.com/

Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
ibaloubi

2006-08-15, 7:00 pm

Pascal Bourguignon wrote:

> ibaloubi <bobofibodibo@aaakyars.com> writes:
>
>
> Indeed, on different processors, or even on the same processor, with a
> different compiler the same C structure declaration can be compiled
> with different offsets.
>
>
> The best class of protocols are the ASCII based one.
>
> 1- ASCII = Americal Standard Code for INFORMATION INTERCHANGE.
>
> 2- Using a line-based ASCII protocol allows you to debug it easily
> using telnet.
>
> 3- Often, ASCII data will be smaller than the equivalent binary
> data. Yes, it's surprizing, but it's true. For strings, you'll get
> the same size, +/- 1; for integers, you have a lot of usual
> integers that need less than 4 bytes to be written in ASCII (1099
> exactly).
>
>
>
> So, you could send the structure:
> with:
>
> struct HostInfo* hi;
> fprintf(socket,"(HOSTINFO \"%s\" %d)\n",hi->m_Host,hi->m_iState);
>
>
> and you can read it with:
>
> if('('==fgets(socket)){
> char type[64];
> fscanf(socket,"[^ ]",&type);
> if(strcmp(type,"HOSTINFO")==0){
> char name[HOSTMAX];
> unsigned int state;
> fscanf(socket,"\"[^\"]\"",&name);
> fscanf(socket,"%d",&state);
> fscanf(socket,")");
> {
> struct HostInfo* hi=malloc(sizeof(struct HostInfo));
> hi->m_Host=newstr(name);
> hi->m_iState=state;
> return(hi); }}
> else{
> error("Unknown type");}}
> else{
> error("syntax error");
> }
>
> for example.
>
>
>
> Then you can easily test it:
>
> telnet localhost $port
> (HOSTINFO "Name" 1)
> ^]quit
>
>

many thanks.
dfeustel@mindspring.com

2006-08-15, 7:00 pm

ibaloubi <bobofibodibo@aaakyars.com> wrote:
> ibaloubi wrote:
>
> I forgot, the struct is:
> struct HostInfo
> {
> enum {ONLINE=0x0001, OFFLINE=0x0002};
> char m_Host[HOSTMAX];
> unsigned int m_iState;
> };
> ( the m_iState is zero when returned ) clue?

Why not just convert the int to a char string before sending it?
--
Using OpenBSD with or without X & KDE?
http://dfeustel.home.mindspring.com
ibaloubi

2006-08-16, 4:01 am

dfeustel@mindspring.com wrote:

> ibaloubi <bobofibodibo@aaakyars.com> wrote:
> Why not just convert the int to a char string before sending it?

hmm, the problem is basically solved. The thing is that my network is
hacked. I have two linuxes, tried the software between the two on the lan,
and it worked, until the recv function in the client started returning
"reset by peer".*S*. ( for no reason actually ).

The most important thing was not to create a functioning software, the
important part was to understand how it works.


Robert Latest

2006-08-16, 8:03 am

On Tue, 15 Aug 2006 15:32:39 +0200,
Nils O. Selåsdal <NOS@Utel.no> wrote
in Msg. <44e1ccf7$1@news.broadpark.no>

> You're likely better off defining a protocol yourself, and not relying
> on the internal represenation of C structs.


No! You're better off using a standardized, portable solution to this
exact problem, namely xdr. Look for "rcpgen" to see how this is turned
into a piece of cake.

robert
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com