2

Is it possible to have winsock's send function block until the packet being sent is received at the other end?

My end goal is to be able to send 5-20mb files while still being able to send small 1kb packets on the same connection. So I was thinking I would have it block until the receiver receives the packet. That way if another small packet is queued it wont be stuck waiting for the rest of the large file to be transferred.

user230821
  • 1,093
  • 3
  • 12
  • 21

5 Answers5

2

Just use two separate TCP connections. They can even connect to the same host and port, the port number at your end will be different.

Stop-and-wait handshaking over any network (i.e. not loopback) would be miserably slow.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

You could send the size of your packages instead

struct MyNetworkPackage {
    int size;
    char* data;
};

if you begin by sending the size, you can deduce on the other side what data belongs to what package.
I've tried to explain winsock in this answer as well.

Community
  • 1
  • 1
default
  • 11,485
  • 9
  • 66
  • 102
0

No. And you don't need to do this.

Steven Sudit
  • 19,391
  • 1
  • 51
  • 53
  • So if I send a large packet and then a smaller one, will tcp send the small while it is still sending the large one? – user230821 Jul 08 '10 at 17:14
  • 1
    TCP is just a stream, if you do one send() call, it might take multiple recv() calls to read that data on the other side. Conversely, several send() calls might be merged, and read with one recv() calls. You have to build your own protocol on top of TCP if you want to send "packets", or get a reply when a packet/message has been received. – nos Jul 08 '10 at 17:16
  • Are you sure? I thought the point of tcp is that it does that kind of management for you. I have never had a time were sending multiple packets at once will get merged into 1 when being received. – user230821 Jul 08 '10 at 17:29
  • Ben's suggestion is right: With two connections, one will not be significantly blocked due to traffic on the other. With just one, the short message will not be received until the long one is. – Steven Sudit Jul 08 '10 at 17:30
  • send calls will never be merged; one call to recv will only read as much as was sent with one call to send. –  Jul 08 '10 at 17:36
  • @brone: I've seen what nos explains in action. What is sent is both merged with other `send` s and split into several `recv` s – default Jul 08 '10 at 17:46
  • @brone: `send` calls definitely can be merged, it's called Nagle's algorithm. http://en.wikipedia.org/wiki/Nagles_algorithm – Ben Voigt Jul 08 '10 at 18:00
  • @high6: Michael suggested a reasonable way to make this stream protocol work a bit more like one that respects packets, but you could also use UDP instead of TCP. Even then, things can happen en-route. – Steven Sudit Jul 08 '10 at 18:09
  • 1
    @brone, you are wrong, TCP does not preserve write/send boundaries. TCP provides a byte stream, not packets/messages. – nos Jul 08 '10 at 19:37
  • @nos: Do you have an example of this happening? Cause I tried sending a ton of 1 byte packets and it still received them 1 at a time even when the buffer was large enough to fit them all. – user230821 Jul 08 '10 at 21:15
  • My evidence was http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx -- see comment for the MSG_PEEK flag, though it's not exactly a model of clarity. I was under the impression this was standard SOCK_STREAM behaviour, and not some Winsock thing, because it's potentially useful, but http://www.opengroup.org/onlinepubs/009695399/functions/recv.html suggests not. (The docs imply that send may not send all of the data anyway, though maybe that's only for non-blocking sockets -- that's probably why.) –  Jul 08 '10 at 23:11
  • 1
    Multiple send() calls CAN be merged together into larger transmission blocks (Nagle), it MAY take multiple send() calls to send a large amount of data, and it CAN take multiple recv() calls to read a single block of data. You definately DO need an application-level protocol in your data to detect the boundaries between messages (which are an appliation-level concept anyway, not a socket concept - at least for TCP). I have also seen this in action many times before. Most major socket libraries I have seen are coded to account for both conditions, because they DO happen. – Remy Lebeau Jul 13 '10 at 01:33
0

I am not sure what we would acheive with this.. Mixing traffic on TCP stream won't server any purpose.. Can you explain what exactly u need to do.. Above all, we can never be sure in TCP that the other application has actually received the pkt (it might just be in their tcp buffers)...

Krishna
  • 11
  • 1
0

It seems that 'send' will block if there is a previous packet still being sent.

user230821
  • 1,093
  • 3
  • 12
  • 21