My client repeatedly sends the mouse position every frame to the server using write. It does this when ever the mouse moves. Thats all it does, so its going pretty fast. It doesnt perform any reads.
My server is in a simple loop, where each frame it:
- performs a read on the connected client socket, decodes the message if there was one, then sets the position of an image to the x/y position from the message
- draws the image
data is read and written using send() and recv()
However im finding there is significant lag. I would have thought it could handle this?
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
UDP is no "faster" than TCP. The only difference is that, in TCP, when a packet is dropped, later packets will be held back until a re-send happens. With UDP, that "blip" will be slightly shorter, but it's not "faster" in the sense of lower typical latency.
Non-blocking I/O is generally not what you want. You want to use select() and recv()/send(). Or you want to use platform-specific asynchronous I/O, such as I/O completion ports on Windows, or evented I/O on Linux, or similar.
Also, anything that goes to/from a cell phone is likely to suffer massive latency (lag) no matter what the protocol. The carrier networks are optimized for voice streams for low latency, and bulk TCP (video, web pages) goes high-latency.
Havent got timing information yet, But disabling nagle seemed to do the trick. Though theres still lag there which I dont think should be there. Im comparing network performance to something like synergy or sharemouse which seem to do basically the same thing.
Non-blocking I/O is generally not what you want. You want to use select() and recv()/send(). Or you want to use platform-specific asynchronous I/O, such as I/O completion ports on Windows, or evented I/O on Linux, or similar.
So far non-blocking does the trick. I have to update as fast as possibly anyway, plus 90% of the time there will be data to read each frame anyway. Would I gain much performance using select asynchronously? Then at the start of each frame I could just read from a buffer rather than doing a recv. Or is that effectively what recv is? Then id have to manage data transfer from the select() thread back to the main render thread :S Scary. Especially if I increase the number of clients I want.
Network programming is hard!
Im just doing this over a wireless using a phone rather than through a carrier network.
select()/recv() is usually called from the main thread, not a separate thread.
recv() copies data from the internal network buffer to your provided buffer.
If every client will send data every frame, and you are OK with the server spin-looping (using 100% CPU,) and you can handle a non-blocking socket refusing a send(), then non-blocking I/O might work for your use case. However, my experience has been that, in the end, such approaches end up switching implementation down the line.
select()/recv() is usually called from the main thread, not a separate thread.
But if I call select from the main thread, wont that block my render loop? I thought the point of select was you could let it set in the background on a separate thread until data arrived, which you then bubbled back up to the main thread somehow
[quote name='hplus0603' timestamp='1328807802' post='4911362']
select()/recv() is usually called from the main thread, not a separate thread.
But if I call select from the main thread, wont that block my render loop? I thought the point of select was you could let it set in the background on a separate thread until data arrived, which you then bubbled back up to the main thread somehow
[/quote]
No, if you call select with appropriate values for the timeout it will return immediately without blocking. You can then check the resultant state and determine if you can read/write from the selected sockets without blocking.
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.