 |
|
 |
|
|
 |
problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Hello, All!
This is defined structure:
/* client message */
typedef struct msg_s {
int msg_type; /* message type: MSG_REQ, MSG_REPLY */
int msg_rc; /* reply code */
char msg_id[BUFSIZ];
char msg_passwd[BUFSIZ];
} msg_t;
...
/* BUFSIZ is defined in standard library and in my system is 8192 */
struct sockaddr_in serv_addr;
...
/* here is 'hp' filled */
/* zero out structure */
memset(&serv_addr, 0, sizeof serv_addr);
/* fill in structure */
serv_addr.sin_family = AF_INET;
memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length);
serv_addr.sin_port = htons(port);
/* create socket based on TCP */
if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
perror("socket() error!");
exit(EXIT_FAILURE);
}
...
/* send buffer to server */
if ( send(sd, m, sizeof(msg_t), 0) == -1 ) {
perror("send() error");
exit(EXIT_FAILURE);
}
Connection is fine, I can observe it on the second-end of link, the only
problem is the corrupted transmission of buffer, I receive only first and
second field of structure 'msg_t' (i.e. 'msg_type' and 'msg_rc') while
'msg_id' and 'msg_passwd' are empty.
I transfer bytes on a x86 host locally, might be the size is too big? I
decreased the buffer size - it didn't help neither.
What may be the problem?
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Roman Mashak wrote:
> Hello, All!
>
> This is defined structure:
>
> /* client message */
> typedef struct msg_s {
> int msg_type; /* message type: MSG_REQ, MSG_REPLY *
/
> int msg_rc; /* reply code */
> char msg_id[BUFSIZ];
> char msg_passwd[BUFSIZ];
> } msg_t;
> ...
> /* BUFSIZ is defined in standard library and in my system is 8192 */
>
> struct sockaddr_in serv_addr;
> ...
> /* here is 'hp' filled */
>
> /* zero out structure */
> memset(&serv_addr, 0, sizeof serv_addr);
>
> /* fill in structure */
> serv_addr.sin_family = AF_INET;
> memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length);
> serv_addr.sin_port = htons(port);
>
> /* create socket based on TCP */
> if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
> perror("socket() error!");
> exit(EXIT_FAILURE);
> }
>
> ...
>
> /* send buffer to server */
> if ( send(sd, m, sizeof(msg_t), 0) == -1 ) {
> perror("send() error");
> exit(EXIT_FAILURE);
> }
>
> Connection is fine, I can observe it on the second-end of link, the only
> problem is the corrupted transmission of buffer, I receive only first and
> second field of structure 'msg_t' (i.e. 'msg_type' and 'msg_rc') while
> 'msg_id' and 'msg_passwd' are empty.
Bear in mind that you might need more than one write/send to send the
entire thing, check the return value of send, use a loop to send
everything. likevise for the receiving end, remember that with TCP a
send on one end can result in multiple reads on the peer, and vice
verca.
Secondily, with sending structs like these, the receiving end must be
compatible, (same platform, compiler options and so on.)
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Hello, Roman!
You wrote to All on Thu, 17 Nov 2005 15:08:04 +0700:
RM> Connection is fine, I can observe it on the second-end of link, the
RM> only problem is the corrupted transmission of buffer, I receive only
RM> first and second field of structure 'msg_t' (i.e. 'msg_type' and
RM> 'msg_rc') while 'msg_id' and 'msg_passwd' are empty.
RM> I transfer bytes on a x86 host locally, might be the size is too big? I
RM> decreased the buffer size - it didn't help neither.
RM> What may be the problem?
To be more correct, data in 'msg_id' and 'msg_passwd' are transferred to the
destination host, but in a inverse manner, for example:
on the source side msg_id is 'user01'
on the destination's end it looks like '\0\0\0\0user01'
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
In article <dlh6o9$28mh$1@relay.tomsk.ru>,
"Roman Mashak" <mrv@tusur.ru> wrote:
> Hello, All!
>
> This is defined structure:
>
> /* client message */
> typedef struct msg_s {
> int msg_type; /* message type: MSG_REQ, MSG_REPLY *
/
> int msg_rc; /* reply code */
> char msg_id[BUFSIZ];
> char msg_passwd[BUFSIZ];
> } msg_t;
> ...
> /* BUFSIZ is defined in standard library and in my system is 8192 */
>
> struct sockaddr_in serv_addr;
> ...
> /* here is 'hp' filled */
>
> /* zero out structure */
> memset(&serv_addr, 0, sizeof serv_addr);
>
> /* fill in structure */
> serv_addr.sin_family = AF_INET;
> memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length);
> serv_addr.sin_port = htons(port);
>
> /* create socket based on TCP */
> if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
> perror("socket() error!");
> exit(EXIT_FAILURE);
> }
>
> ...
>
> /* send buffer to server */
> if ( send(sd, m, sizeof(msg_t), 0) == -1 ) {
> perror("send() error");
> exit(EXIT_FAILURE);
> }
>
> Connection is fine, I can observe it on the second-end of link, the only
> problem is the corrupted transmission of buffer, I receive only first and
> second field of structure 'msg_t' (i.e. 'msg_type' and 'msg_rc') while
> 'msg_id' and 'msg_passwd' are empty.
Are you checking the return value of recv(), to be sure you've received
everything? You need to call recv() in a loop until you get everything,
or use the RECV_WAITALL option if your OS supports it.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Hello, Barry!
You wrote on Thu, 17 Nov 2005 01:47:06 -0500:
BM> Are you checking the return value of recv(), to be sure you've received
BM> everything? You need to call recv() in a loop until you get
BM> everything, or use the RECV_WAITALL option if your OS supports it.
I'm checking only error status of 'recv()':
int n; /* number of received bytes */
if ( -1 == (n=recv(sd, m, sz, 0)) ) {
/* log error message */
exit(EXIT_FAILURE);
}
If I call recv() in a loop, how should I deal with receiving buffer, will it
be automatically added and aligned if necessary or I've to do it manually?
How can I check if Linux supports RECV_WAITALL or not? Is it done via
setsockopt() ?
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Hello, "Nils!
You wrote on Thu, 17 Nov 2005 07:40:27 +0100:
NOS> Bear in mind that you might need more than one write/send to send the
NOS> entire thing, check the return value of send, use a loop to send
NOS> everything. likevise for the receiving end, remember that with TCP a
NOS> send on one end can result in multiple reads on the peer, and vice
NOS> verca.
May it look like this?
msg_t *m;
while (n < sizeof(msg_t) ) {
int n;
if ( -1 == (n=recv(sd, m, sz, 0)) ) {
...
}
}
NOS>Secondily, with sending structs like these, the receiving end must be
NOS>compatible, (same platform, compiler options and so on.)
In my case they're absolutely identical, because it's all running on the
same host (I think subject of my post is confusing, sorry)
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Roman Mashak wrote:
> Hello, "Nils!
> You wrote on Thu, 17 Nov 2005 07:40:27 +0100:
>
> NOS> Bear in mind that you might need more than one write/send to send th
e
> NOS> entire thing, check the return value of send, use a loop to send
> NOS> everything. likevise for the receiving end, remember that with TCP a
> NOS> send on one end can result in multiple reads on the peer, and vice
> NOS> verca.
> May it look like this?
>
> msg_t *m;
>
> while (n < sizeof(msg_t) ) {
> int n;
> if ( -1 == (n=recv(sd, m, sz, 0)) ) {
> ....
> }
> }
No, provided m is a pointer-to-a-msg_t,
unsigned char *buf = (unsigned char*)m;
ssize_t recvd = 0;
ssize_t sz = sizeof(msg_t);
while (recvd != sizeof(msg_t) ) {
ssize_t n;
if ( 0 <= (n=recv(sd, buf+recvd, sz-recvd, 0)) ) {
if(n == 0) {
/*gracefully closed*/
break;
} else {
/* error !*/
break;
}
recvd += n;
}
}
similar loop for the sending end is needed. Make the above a more
generic function that uses read(2) for future use.
Alternativly, for the receiving end:
if ((n=recv(sd, m, sizeof *m, MSG_WAITALL)) != sizeof *m) { /*we didn't
get it all :-( */
if(n == 0) {
/* gracefully closed, got nothing.. */
} else if (n == -1){
/* error ! */
} else {
/* we just got some of it for subtle reasons */
}
/* ... bail out ? */
} else {
/* We received it all */
}
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 07:52 AM
Nils, thank you for example! I have couple of questions.
NOS> similar loop for the sending end is needed. Make the above a more
NOS> generic function that uses read(2) for future use.
Why is read() better than recv(), or it's more general?
NOS>Alternativly, for the receiving end:
NOS>if ((n=recv(sd, m, sizeof *m, MSG_WAITALL)) != sizeof *m) { /*we di
dn't
why do you use here sizeof *m ? It will give always 4 bytes as far as I
understand, since it's a pointer, or there's some hidden point I'm unable to
catch?
NOS>get it all :-( */
NOS> if(n == 0) {
NOS> gracefully closed, got nothing..
NOS> } else if (n == -1){
NOS> error !
NOS> } else {
NOS> we just got some of it for subtle reasons
NOS> }
NOS> ... bail out ?
NOS>} else {
NOS> We received it all
NOS>}
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 11:13 PM
Roman Mashak wrote:
> Nils, thank you for example! I have couple of questions.
>
> NOS> similar loop for the sending end is needed. Make the above a more
> NOS> generic function that uses read(2) for future use.
> Why is read() better than recv(), or it's more general?
>
> NOS>Alternativly, for the receiving end:
> NOS>if ((n=recv(sd, m, sizeof *m, MSG_WAITALL)) != sizeof *m) { /*we
didn't
> why do you use here sizeof *m ? It will give always 4 bytes as far as I
> understand, since it's a pointer, or there's some hidden point I'm unable
to
> catch?
sizeof p would yield the size of the pointer,
sizeof *p would yields the size of what it points to.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: problem with transmitting structure over network |
 |
 |
|
|
11-17-05 11:13 PM
Roman Mashak wrote:
> Nils, thank you for example! I have couple of questions.
>
> NOS> similar loop for the sending end is needed. Make the above a more
> NOS> generic function that uses read(2) for future use.
> Why is read() better than recv(), or it's more general?
Yes, it's more general, in that you can use it on all sorts of
file descriptors. Just for sockets, recv is fine.
[ Post a follow-up to this message ]
|
|
|
 |
|
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 04:47 PM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|