简体   繁体   中英

Winsock WSAAsyncSelect sending without an infinite buffer

This is more of a design question than a specific code question, I'm sure I am missing the obvious, I just need another set of eyes.

I am writing a multi-client server based on WSAAsyncSelect, each connection is made into an object of a connection class I have written which contains associated settings and buffers etc.

My question concerns FD_WRITE, I understand how it operates: One FD_WRITE is sent immediately after a connection is established. Thereafter, you should send until WSAEWOULDBLOCK is received at which point you store what is left to send in a buffer, and wait to be told that it is ok to send again.

This is where I have a problem, how large do I make this holding buffer within each connections object? The amount of time until a new FD_WRITE is received is unknown, I could be attempting to send a lot of stuff during this period, all the time adding to my outgoing buffer. If I make the buffer dynamic, memory usage could spiral out of control if for whatever reason, I am unable to send() and reduce the buffer.

So my question is how do you generally handle this situation? Note I am not talking about the network buffer itself which winsock uses, but one of my own creation used to "queue" up sends.

Hope I explained that well enough, thanks all!

Naturally, the correct design depends on the nature of your application.

Some programs can predict the amount of data that can be generated before something must be done with it, so they can use a fixed-size buffer. One protocol I designed, for instance, had a command-response structure and a 2-byte length prefix, so I could use 64K buffers and know I'd never overflow them. If a buffer is full, the program must be waiting for a reply before it is allowed to send data from that buffer, so no more data will be added to that buffer.

Another good use for fixed-size buffers is when the data comes from another I/O source. Consider a web server: at its most basic, it slurps files from disk and spits them out on the wire. You therefore know how much you are reading from disk at a time, so you know how big your buffers must be.

I'm having trouble coming up with a good reason to use dynamic buffers.

The main reason you don't need them is TCP's sliding window . If one of the connection peers stops receiving data, the remote peer's stack will stop sending data when the TCP window fills up. The unread data will stay in the receiving stack's buffers until the program it was sent to requests it. This gives the receiver a way to throttle the incoming data to a level it can handle. As far as I can tell, that makes fixed-size buffers practical under all conditions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM