Hello to all,
I have a client/server app and i have the following prob:

Client site:
The client sends a small header to the server letting it know that some data are followed
The client continues and starts sending the data.

server site:
Server Supposly should get the small header and parse it. BUT!


It receives BOTH the small header and part of the data in one single recv! WHY!? I only first to receive the header first. The header btw is just 3 bytes long.

snippet::




.elseif uMsg == WM_CLIENTSOCKET
mov eax, lParam
.if ax == FD_READ
shr eax, 16
.if ax == NULL
; Get command / Receive 3 bytes only for the header
invoke recv, wParam, addr buffer_recv, SIZEOF buffer_recv,0
invoke ParseCommand, hWin, wParam, addr buffer_recv, buffer_recv_size




Can someone point me where i am wrong?
thanks a lot
Posted on 2003-04-14 12:02:50 by Ray
I assume you're doing TCP. That's how TCP works - it's a STREAM, while UDP is a DATAGRAM (packet). TCP (righthly so) collects multiple sends, and tries to send out only whole packets, to reduce network load.
Posted on 2003-04-14 12:12:41 by f0dder
Thanks F0d.

How would you solve this problem if it was you? any quick workarounds?
Posted on 2003-04-14 12:55:32 by Ray
start by recv()'ing until you have the entire header. ie, don't recv for your buffer length, recv for the sizeof(header).

Then you can recv() for the header.datalength (or however you put it).

And if anybody suggests TCP_NODELAY, ignore them.
Posted on 2003-04-14 13:01:48 by f0dder
Why not enclose everything sent within a header and some number/numbers meaning the data is ended, like

header
data
dataEnds

and always parse the received bytes according to that structure? not possible?
EDIT:maybe fodders idea better.
Posted on 2003-04-14 13:02:01 by david
Using a "dataend" signature means you cannot send just any type of data, and that "dataend" occuring in normal data would have to be escaped. Makes me think of stupid things like modem protocols.

remember, if you use nonblocking sockets, you might not receive as many bytes as you requested before recv() returns... I personally prefer blocking sockets + threads.
Posted on 2003-04-14 13:07:20 by f0dder
F0d,

I was playing around and I did try your suggestion but i sured messed up somewhere and didn't work! suprise! geez..
I changed a bit the communication process between server and client and solved my problem. What i did is that I "forced" the client to wait for a confirmation from the server before starting to send that real data. This solved my problems.

And you are right! These non-blocking sockets always confuse the hell out of me:confused:
I hope next time i will remember to go with blocking+threads! geez..

Thomas, u reading? How about that tut :) non-blocking? hehe..just kidding man..whenever u r ready.:alright:

David: thanks for ur recomendation.
Posted on 2003-04-14 15:07:48 by Ray


remember, if you use nonblocking sockets, you might not receive as many bytes as you requested before recv() returns... I personally prefer blocking sockets + threads.

The same thing holds for blocking sockets, send will send the number of bytes requested but recv might still receive less...

Originally posted by Ray"]
F0d,
I was playing around and I did try your suggestion but i sured messed up somewhere and didn't work! suprise! geez..
I changed a bit the communication process between server and client and solved my problem. What i did is that I "forced" the client to wait for a confirmation from the server before starting to send that real data. This solved my problems.

Still, it's easy to have some kind of buffer mechanism that takes a TCP stream, parses it and calls some kind of function on each received 'message'.

And you are right! These non-blocking sockets always confuse the hell out of me:confused:
I hope next time i will remember to go with blocking+threads! geez..

The disadvantage of blocking sockets is that you have no control over your thread while a socket is blocking (except for some functions with timeouts).

Thomas, u reading? How about that tut :) non-blocking? hehe..just kidding man..whenever u r ready.:alright:

Next chapter will still be blocking sockets (server this time) so be patient :)

Thomas
Posted on 2003-04-14 15:21:29 by Thomas

The same thing holds for blocking sockets, send will send the number of bytes requested but recv might still receive less...

Humm, it's definitely possible for you to recv() less bytes than has been sent (if you specify a smaller amount), but shouldn't recv(), on a blocking socket, wait until it has received "len" bytes, the connection is terminated, or (if you've been setting socket options) the timeout happens?


Still, it's easy to have some kind of buffer mechanism that takes a TCP stream, parses it and calls some kind of function on each received 'message'.

Indeed it is, and better than inventing your own "ACK" scheme. You lose advantages of TCP if you constantly have to wait for ACKs.


The disadvantage of blocking sockets is that you have no control over your thread while a socket is blocking (except for some functions with timeouts).

What about using the event notification stuff? You can specify timeouts that way, probably a bit better than using ioctlsocket and specifying timeout.
Posted on 2003-04-14 15:45:51 by f0dder
Originally posted by f0dder
Humm, it's definitely possible for you to recv() less bytes than has been sent (if you specify a smaller amount), but shouldn't recv(), on a blocking socket, wait until it has received "len" bytes, the connection is terminated, or (if you've been setting socket options) the timeout happens?

No, the len parameter indicates the maximum buffer size, not the number of bytes to receive. The docs say:
For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return ]b]as much information as is currently available[/b]?up to the size of the buffer specified.

If you want an example, run the example from my latest network chapter tutorial, the buffer used has 128 bytes but even if the server's response is less, the recv will return.

What about using the event notification stuff? You can specify timeouts that way, probably a bit better than using ioctlsocket and specifying timeout.

Do you mean WSAEventSelect? That's non-blocking sockets. Or events in general? Then you still need some kind of polling mechanism (although a more relaxed one than a busy waiting loop because of the timeout).

Thomas
Posted on 2003-04-14 17:23:42 by Thomas
Been a while since I did any socket coding, probably it shows :)


If you want an example, run the example from my latest network chapter tutorial, the buffer used has 128 bytes but even if the server's response is less, the recv will return.

Ok - and this is not because server closes the socket? Good thing to keep in mind - always loop your recv() calls into you get error or the amount of data you wanted.


Do you mean WSAEventSelect? That's non-blocking sockets. Or events in general? Then you still need some kind of polling mechanism (although a more relaxed one than a busy waiting loop because of the timeout).

WSAEventSelect indeed. I was considering that "blocking" because you'd usually "block" on WaitForSingleObject - silly me, they're of course nonblocking.

Thanks for clearing up stuff a bit, I'll try to not forget the information this time. And thanks a lot for your tutorial stuff, you have a nice writing style that is easy to follow. The current stuff has mostly served to refresh my mind, and I'm definitely looking forward to IO completion ports, especially how they would differ from setting up your own queue of working threads etc.

:stupid:
Posted on 2003-04-14 17:32:55 by f0dder
Originally posted by f0dder
Ok - and this is not because server closes the socket? Good thing to keep in mind - always loop your recv() calls into you get error or the amount of data you wanted.

Good point :), but I've tested it and it isn't because of the connection closing. Although I must say the documentation does not explicitly say it may receive less (like it says clearly for send on non-blocking sockets), but it doesn't say it will receive len bytes either.

WSAEventSelect indeed. I was considering that "blocking" because you'd usually "block" on WaitForSingleObject - silly me, they're of course nonblocking.

It's blocking in some way, yes :).

Thanks for clearing up stuff a bit, I'll try to not forget the information this time. And thanks a lot for your tutorial stuff, you have a nice writing style that is easy to follow. The current stuff has mostly served to refresh my mind, and I'm definitely looking forward to IO completion ports, especially how they would differ from setting up your own queue of working threads etc.

Thanks :) I can't wait digging into the I/O completion ports too but it has to wait, might not be the best starting point for beginners ;).

Thomas
Posted on 2003-04-14 17:41:59 by Thomas
f0dder: I moved your last post to a seperate thread because it's starting to get a bit off-topic.
Here's the new thread:
http://www.asmcommunity.net/board/showthread.php?s=&postid=96721

Thomas
Posted on 2003-04-15 10:37:05 by Thomas