Sign in to follow this  

Basic TCP/IP Question

This topic is 669 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

I'm new to network programming and have to write a tool that runs on Windows and communicates with a Linux box over the network.  The linux box has a TCP/IP server setup using c++ with boost.  

 

My tool in Windows needs to connect.  For the Windows side, I am writing the tool in C# and looked at this tutorial: http://www.codeproject.com/Articles/10649/An-Introduction-to-Socket-Programming-in-NET-using

 

Basically, the linux box is going to send packets with "event data" to the Windows client at certain times.  What's the best way for the client to wait for incoming data?  The tutorial above uses a while loop to send/receive data over the network stream.  But is just looping and continuously polling for a packet the right design?

Share this post


Link to post
Share on other sites

This depends on further requirements.  While I would say it is bad form to use a busy loop, if it is appropriate or not is really dependent on further requirement information.  For instance, if your tool needs to do any significant work when it receives an event, you likely want to use an asynchronous solution with a queue of work to be done.  It is really dependent on further information about your requirements though..

Share this post


Link to post
Share on other sites
If you can block, that's the easiest.
If you can't block, then you have several options:

- If your client has some kind of loop, you can poll the TCP stream each loop, reading as much data as available and processing any complete messages. There will always be the possibility of incomplete messages, so make sure you can store a partially received message across iterations of such a loop.
- If you do not have a loop and you can use C# 5.0, then you can potentially use async/await.
- If you do not have a loop, nor async/await, you can use a thread which does the blocking-style reads internally and somehow posts complete messages back to whatever thread(s) need to process them (or processes them itself, if your messages do not need to be processed on the UI thread).
- If you don't like writing your own thread function and don't have async/await, you can use a BeginRead/EndRead pair with callbacks. (You can also use BeginRead/EndRead in polling mode, if you want) Edited by Nypyren

Share this post


Link to post
Share on other sites
Generally polling a socket by reading and checking for eagain is not the best option perormance wise especially if you have multiple sockets.

For Linux you should use epoll(), freebsd should use kqueue() and on windows look into io completion ports.

If you can block do so as others have said but never fall into the trap of one thread per socket. Look into thread pools which also works well with what I outlined above.

At a bare minimum use select() but again when you have multiple sockets and not many are active this soon deteriorates in performance.

Hope this helps!

Share this post


Link to post
Share on other sites
Look up the term "evented I/O", which is the typical way to build high-performance networking (or any kind of I/O).

I've personally been pretty disappointed with the standard .NET facilities for this, though. It's all based on async I/O which is somewhat harder to use for (often) little gain. You can build your own evented I/O system over non-blocking sockets and such.

If any part of your stack is in C or C++, consider libraries like libuv, libev, or libevent. For C#... honestly, let me know if you find an equivalent, because I never have, which is one of the reasons I gave up on using C# for anything and rather stick to C++ (even for tools; Qt obviates the need for C# there), unless of course working in Unity or the like.

Share this post


Link to post
Share on other sites
A while loop on a BLOCKING socket is perfectly fine. The thread doing the reading on the socket will just suspend in the kernel until data is availbale.

A while loop on a non-blocking socket will consume all of the available CPU, so that's not that great, unless you're doing scary-crazy ultra-low-latency stuff where you'd expect to see a full stream of packets anyway.

Doing a while loop on a non-blocking socket once per iteration through your game main loop is a fine thing to do, though. If you're running simulation and/or rendering in addition to networking, a very simple structure is:

while (true) {
  read_input();
  while ((size = recvfrom(socket, buffer, ...)) > 0) {
    process network data
  }
  simulate();
  render();
}

Share this post


Link to post
Share on other sites

This topic is 669 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this