Jump to content
  • Advertisement
Sign in to follow this  
DjMaSh

Network bottle neck?

This topic is 2499 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im writing my first ever client/server model, and im finding my implementation is too slow, but im not sure what the bottle neck is.

It consists of 1 client and 1 server,using BSD sockets. Both sockets are created using:


socket(AF_INET, SOCK_STREAM, 0);


The server socket is set to non blocking using:


u_long iMode=1;
ioctlsocket(Socket,FIONBIO,&iMode);


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?

Im not sure where my bottle neck is?

Share this post


Link to post
Share on other sites
Advertisement
I havent measured times exactly yet as I just got it up and running last night.

I havent disabled nagle either.

Ill try these things tonight.

After reading a bit, it sounds like UDP might be more suitable as I require fast response times.

But is it really necessary, or should I be able to get reasonable 1:1 motion using tcp?

Share this post


Link to post
Share on other sites
I should also point out, the client is running on an iphone, and the server is on a windows box, so server is using winsock, and client is using bsd

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

How fast is a frame?
Have you disabled Nagle?


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.

Any other tips to speed things up???

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
But if I call select from the main thread, wont that block my render loop?[/quote]

It's called "non-blocking" for a reason.

Share this post


Link to post
Share on other sites

[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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!