Send() Blocking inconveniently long
Heya, My game features an auto update, and once in awhile when a user with a very slow connection connects and needs to update, the entire lobby will freeze up waiting for the last send() call to complete. I'm using blocking TCP sockets... And the thing about just switching to non-blocking is that I would have to change a lot more, and more or less implement my own pipeline because of multithreading issues, which would lead to stalling anyway. Isn't there some way to determine if attempting to send a certain number of bytes will block? PS When I say _LONG_ wait times, I mean longer than several minutes. Clearly the send call is simply blocking without returning, and using select() with the writefds parameter to check if the next update packet can be sent helps only minimally. My packet sizes are 700 bytes... Would cutting it to 200 bytes or 100 bytes have that much of an effect? Walt
send() should only block if the local buffer is full. The local buffer should only get full if the other end is not reading from its local buffer.
So basically, you should be able to send at least your local buffer + their local buffer before it starts blocking.
If that happens, something is usually a bit wrong. I find that using nonblocking sockets for writing is very inconvenient. You can't guarantee that stuff will be sent because send() returns EWOULDBLOCK and doesn't queue the data, so you have to remember what you would have sent them.
In practice this probably involves creating an application-level buffer. But if that buffer becomes too large, you'll have to assume that the other end has gone away, so you should close the socket.
If you're sending messages which each contain updates to the same information (i.e. each isn't required), you could just discard that message if you get EWOULDBLOCK.
Mark
So basically, you should be able to send at least your local buffer + their local buffer before it starts blocking.
If that happens, something is usually a bit wrong. I find that using nonblocking sockets for writing is very inconvenient. You can't guarantee that stuff will be sent because send() returns EWOULDBLOCK and doesn't queue the data, so you have to remember what you would have sent them.
In practice this probably involves creating an application-level buffer. But if that buffer becomes too large, you'll have to assume that the other end has gone away, so you should close the socket.
If you're sending messages which each contain updates to the same information (i.e. each isn't required), you could just discard that message if you get EWOULDBLOCK.
Mark
So I should just convert my sockets to nonblocking and use select() to poll? No other real way around this?
And do BOTH ends have to be similarly nonblocking or blocking? For instance, if i change the server to nonblocking to prevent such hangups, but I know for a fact that these hangups do not and will not occur client-side, then at least for the autoupdate will blocking sockets cooperate with nonblocking? I'm assuming they do, just making sure.
And do BOTH ends have to be similarly nonblocking or blocking? For instance, if i change the server to nonblocking to prevent such hangups, but I know for a fact that these hangups do not and will not occur client-side, then at least for the autoupdate will blocking sockets cooperate with nonblocking? I'm assuming they do, just making sure.
If your server uses non-blocking sockets, then you know for sure that the server won't block. The client doesn't matter.
enum Bool { True, False, FileNotFound };
A'ight, thanks for the help :)
One more Q though, I successfully ported to nonblocking, but will I need to also change my UDP send() and recv()? Or does UDP stay consistent since it's relatively nonblocking anyway.
[Edited by - shadowman131 on February 22, 2005 7:50:07 PM]
One more Q though, I successfully ported to nonblocking, but will I need to also change my UDP send() and recv()? Or does UDP stay consistent since it's relatively nonblocking anyway.
[Edited by - shadowman131 on February 22, 2005 7:50:07 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement