3

MSDN states "For a Winsock application, once the WSASend function is called, the system owns these buffers and the application may not access them."

In a server application, does that mean that if I want to broadcast a message to multiple clients I cannot use a single buffer that holds the data and invoke WSASend on each socket with that one buffer?

Megatron
  • 123
  • 1
  • 11
  • possible duplicate of [An IOCP documentation interpretation question - buffer ownership ambiguity](http://stackoverflow.com/questions/3028376/an-iocp-documentation-interpretation-question-buffer-ownership-ambiguity) – Remy Lebeau Mar 14 '15 at 19:02
  • @Remy: I think not a duplicate; this question is specifically about using a single read-only buffer for multiple identical write operations, whereas the OP in the other question wanted to deallocate or reuse (i.e., write to) the buffer. It isn't unreasonable to suppose that using a read-only buffer for multiple identical writes might be a special case (though I suspect the answer is that it isn't). – Harry Johnston Mar 14 '15 at 22:52
  • @HarryJohnston: Nothing in this OP's question says the buffer being sent is read-only. But it should be pretty clear and obvious that if multiple `WSASend()` operations are reading from the same buffer at the same time then that buffer must not be touched for any reason (freed, overwritten, etc) until **all** of the pending `WSASend()` operations have finished, just like the documentation (and the other answer) suggests. Overlapped I/O, whether for sockets or file or whatever, does not copy outgoing data to an internal buffer, it reads from the original buffer until the I/O is finished. – Remy Lebeau Mar 14 '15 at 23:27
  • @RemyLebeau: I believe the question is whether multiple WSASend() operations *can* read from the same buffer at the same time. Does calling WSASend() again on the same buffer count as "accessing" that buffer? – Harry Johnston Mar 15 '15 at 00:21
  • @HarryJohnston: That was what I meant. The thing with the "accessing" sounds a bit ambigous to me. – Megatron Mar 15 '15 at 00:26
  • @HarryJohnston: read, yes. write/free, no. – Remy Lebeau Mar 15 '15 at 00:32

1 Answers1

5

I don't have a documentation reference that confirms this is possible but I've been doing it for years and it hasn't failed yet, YMMV.

You CAN use a single data buffer as long as you have a unique OVERLAPPED structure per send. Since the WSABUF array is duplicated by the WSASend() call and can be stack based I would expect that you COULD have a single WSABUF array, but I've never done that.

What you DO need to make sure that you keep that single data buffer "alive" until all of the data writes complete.

Broadcasting like this can complicate a design if you tend to structure your extended OVERLAPPED so that it includes the data buffer, but it does avoid memory allocation and memory copying.

Note: I have a system whereby my extended OVERLAPPED structures include the data buffer and operation code and these are reference counted and pool and used for sends and recvs. When broadcasting a buffer I use a separate "buffer handle" per send, this handle is just an OVERLAPPED structure extended in a different way, it holds a reference to the original data buffer and has its own reference count. When all of the broadcast sends have completed all of the buffer handles will have been released and these will, in turn, have released the underlying data buffer for reuse.

Len Holgate
  • 21,282
  • 4
  • 45
  • 92