Jump to content
  • Advertisement
CelticSir

How to recieve messages from server with TCPClient via Async

Recommended Posts

Hi

I have set up my TcpClient to connect to my server and that works fine. But i am a bit confused how i read messages from the network stream with it continuously running via async, without ever closing the connection ?

My TcpClient Manager class has:
 

        public async Task<bool> Connect(string address, int port)
        {
            try
            {
                await _tcpClient.ConnectAsync(address, port);
                IsConnected = true;
                return true;
            }
            catch(Exception e)
            {
                Debug.Log(e);
                return false;
            }
        }
        public async Task<int> Read(byte[] readBuffer)
        {
            if (!IsConnected) return -1;

            using (var networkStream = _tcpClient.GetStream())
            {
                try
                {
                    var bytesRead = await networkStream.ReadAsync(readBuffer, 0, readBuffer.Length);
                    return bytesRead;
                }
                catch (Exception e)
                {
                    Debug.Log(e);
                    IsConnected = false;
                    return -1;
                }
            }
        }

 

So i thought to just run a co-routine and call Read constantly to get the most recent message, but that doesn't make much sense to me since a co-routine would be blocked with the await. How is this actually done? The MS Docs don't have very good Async examples with the TcpClient class so i don't know fully get how to keep calling Read correctly.

Edited by thefollower

Share this post


Link to post
Share on other sites
Advertisement

Without having looked at the docs myself, two solutions come to mind:

  1. Periodic polling (if lag in the read isn't important)
  2. Spawning a new thread (if lag is important)

Have you tried either of these? If so, what was the result?

Share this post


Link to post
Share on other sites

To receive from a TCP stream, you need to always have a read request outstanding.

Inside the completion callback, you should put the data you received into an incoming buffer, and queue another receive request.

Note that data will come in "chunks" that may have no relation to how it was sent -- TCP is not a packet based protocol, and reading from a TCP stream is a bit like reading from a file that returns some random number of the next bytes from the file each time you read some. Thus, you need to continually look at the head of your received buffer, and see if there's a full packet in there, and if so, decode and remove that packet from the buffer.

Typically, you will prefix each (binary( packet by the length (number of bytes) in the packet, or you will terminate each (text) packet with a special character sequence, like \r\n.

The fact that you immediately call await kind-of eliminates the benefit of the asynchronous TCP, though. The whole point is that, each time through your main loop, you will "read whatever is there" and append to the end of your incoming buffer, then you will decode any whole packets found at the head of the buffer. If you instead dedicate a thread to reading, you can read in blocking fashion, and then do the same decoding, although you then have the problem of sending the ready packets across threads to be correctly processed by your game logic.

Share this post


Link to post
Share on other sites

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

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!