PDA

Click to See Complete Forum and Search --> : [Guide] ]Winsock] Packets Sticking together?


Pino
Jul 16th, 2004, 12:57 PM
Ok here is another quick guide demonstrating what to do if your data is getting 'stuck' together,

I use this method for most of my winsock Applications,

Thanks

PINO

azteched
Jul 19th, 2004, 12:12 PM
Fair enough, but it sort of misses the point. The data isn't being "stuck together", because the data is sent in a continuous stream - TCP/IP is a stream protocol. That needs to be clear in the document really, because a lot of beginner winsock programmers make the mistake of thinking one "send" call will correspond to one "receive" call on the remote host.

Pino
Jul 19th, 2004, 12:47 PM
fair comment, i'll add it to the document as soon as i get chance

Wokawidget
Aug 16th, 2004, 05:22 AM
No offence Pino, but that code won't work properly.
What if the data sent is larger than the packet size???

Have a look at the code inside the Socket class...(not clsSocket)
Look at the code in SendData and mobjSocket_OnDataArrival.
As you can see there is some pretty heft coding to deal with merging packets and stuff :(

The code attached to this post uses a winsock class
,clsSocket which is a version of the cSocket class available over the web.
However, the senddata and mobjSocket_OnDataArrival code CAN BE EASILY transfered to work on a winsock control in a form.

Woka

Pino
Aug 16th, 2004, 05:32 AM
whenever i have created muliplayer games or chat rooms etc i have allways used that cod and it has never failed me, i dont understand what you mean?

Wokawidget
Aug 16th, 2004, 05:56 AM
Hehe...same thing in 2 threads.

Just to keep this thread correct, your method works fine...UNLESS the data sent is > 4k (packet size) in which case you need to merge packets back together. Your code doesn't do this, but works perfectly for data < 4k

Woof

azteched
Aug 16th, 2004, 02:16 PM
"Packet size" has no meaning in TCP/IP. Your code *must* assume that the data can arrive in any way it wants (though it's guaranteed to be in order). Unfortunately there's a lot of broken code out there..

Vishalgiri
Aug 26th, 2004, 09:17 PM
Originally posted by azteched
"Packet size" has no meaning in TCP/IP. Your code *must* assume that the data can arrive in any way it wants (though it's guaranteed to be in order). Unfortunately there's a lot of broken code out there..

intresting, can you explain?

azteched
Aug 27th, 2004, 06:32 AM
TCP is a stream protocol. It works on a stream of bytes - Winsock knows nothing about your application-defined messages/packets. At the transport layer the data is sent in packets, but these don't necessarily have any relation to what you send in a single "send" command.

Wokawidget
Aug 27th, 2004, 06:44 AM
I think people, including me, use the word "packets" very loosely.

I call a packet the data buffer that is got from DataArrived event.

Wpoof

azteched
Aug 27th, 2004, 06:50 AM
Which has no definite size.

Wokawidget
Aug 27th, 2004, 07:10 AM
If I send 10Mb then the data packets are 4k long, everytime.

Woof

azteched
Aug 27th, 2004, 08:21 AM
With the Winsock Control?

Wokawidget
Aug 27th, 2004, 08:27 AM
Yup.

Wokawidget
Aug 27th, 2004, 08:32 AM
It's not the winsock control, but the cSocket class that can be used to replace the winsock control. Although I remember exactly the same thing when I used to use the winsock control.

I lied, the "packet" size is in fact:

(debug.print results)

8192
8192
8192
8192
8192
etc

Just tested it by sending a 9mb file.

Woof

azteched
Aug 27th, 2004, 08:34 AM
Yeah, exactly. I bet the underlying implementation of the control is to send a maximum of 4k per send() call. It's also receving 4k per recv() (unless there isn't a 1 to 1 correspondence between recv() calls and DataArrived events), but that's not guaranteed anywhere by TCP. It'll likely receive 4k per recv() over the loopback, or over a local network, because there's essentially no over-the-wire delays. Bottom line: Don't ever assume how much data a single recv() call will return with TCP. It may work in testing, but sooner or later code that makes assumptions like that *will* break.

azteched
Aug 27th, 2004, 08:39 AM
addition:

* is to send a maximum of 4k per send() call

..and to receive a maximum of 4k per recv()

(or 8k, or whatever).

Wokawidget
Aug 27th, 2004, 08:47 AM
I completely agree with you.
Whenever I use winsock I encode the data so the server knows when it's received it all.
It adds the "packets" together until the whole data has been received.
U see LOADS of users here not bothering with the concatonation of the "packets" and they assume that ALL the data is received in one go.
Keep telling people, but they don't seem to listen :(

Woof

azteched
Aug 27th, 2004, 08:49 AM
Yup :) The problem is I think that when people test their code locally, it does work because the data doesn't have to traverse the 'net, but then when it gets released, they get a shock.

lonestarcomps
Feb 24th, 2006, 02:39 PM
So the winsock send_complete event shouldn't be used when recieving data, packets delimited or otherwise - because the send isn't ever complete being that it's a stream?

lonestarcomps
Feb 24th, 2006, 02:40 PM
Initially I thought the send_complete event was for the completion of each 8k packet, but if that's the case then what is the send_progress event for ?

Wokawidget
Feb 25th, 2006, 06:18 AM
it's not per packet.

SendComplete fires when the whole data has been sent, send progress fires periodically while sending.

Woka

lonestarcomps
Feb 25th, 2006, 08:45 AM
so send complete is raised when the last bit of data in the stream is sent?

Wokawidget
Feb 25th, 2006, 08:56 PM
yes. suprisingly...exactly what you would expect from an event called SendComplete :D

It's not going to mean it's 1/2 way through is is ;)

Woka

EntityReborn
Oct 5th, 2008, 01:59 PM
I've attached a class I am using for my current project, and was wondering, does it fix the packet problem? Logically in my mind, it should work for both Split Packets as well as Appended Packets. Using the term Packets loosely of course.

PS. Sorry for re-opening an OOLD post.

dilettante
Feb 7th, 2009, 06:31 AM
If everyone simply stopped saying "packets" we'd all be way ahead.

The Winsock control's SendComplete event is raised when the Winsock control can accept another SendData without blocking. It does not mean that the buffers are completely empty.

You couldn't pay me to use cSocket/cSocketMaster. They are quite flawed in several ways the authors were never able to correct and I gave up tinkering with them myself years ago. By VB6 SP6 the Winsock control was an extremely robust tool.

The 8K that keeps coming up is the underlying socket's TCP buffer size. The Winsock control uses additional paged memory buffers in front of the socket's non-paged buffer for output to help smooth out operation in VB6. It relies on the 8K input buffer though for receiving, which is why you see DataArrivals of up to 8K but no larger.

DigiRev
Feb 9th, 2009, 12:39 AM
I used to just delimit data but then realized it's better to just send the length in a header.

Then it's easy to always send data and have it be 100% reliable no matter if "packets" get joined together, split up, etc.

FireXtol
Jun 17th, 2010, 12:49 AM
If everyone simply stopped saying "packets" we'd all be way ahead.

The Winsock control's SendComplete event is raised when the Winsock control can accept another SendData without blocking. It does not mean that the buffers are completely empty.

You couldn't pay me to use cSocket/cSocketMaster. They are quite flawed in several ways the authors were never able to correct and I gave up tinkering with them myself years ago. By VB6 SP6 the Winsock control was an extremely robust tool.

The 8K that keeps coming up is the underlying socket's TCP buffer size. The Winsock control uses additional paged memory buffers in front of the socket's non-paged buffer for output to help smooth out operation in VB6. It relies on the 8K input buffer though for receiving, which is why you see DataArrivals of up to 8K but no larger.

cSocket is about 10x less latent. :wave:

Care to qualify your statements about the socket classes you used, or the specific revisions?