0

so i'm trying to create a system that uses a TcpClient to send and recieve data from a server. I have a thread listening for data coming in.

What I want is to be able to make a method which can:

Write to the stream > Wait for response > Process response

But at the same time, other irrelevant data may also come in during this time, so I can't just do:

writer.WriteLine("");
string response = reader.ReadLine();

I was looking at 'callbacks' in this question > Callbacks in C# and it seems like this is the way I need to go, but I'm not entirely sure how I can proceed with this.

Any help with this would be great, thanks!

Edit for Jim Mischel:

This is the sort of thing I want to achieve:

public bool Login(string username, string password) {
    writer.Write("{ \"username\" : \"" + username + "\", \"password\" : \"" + password + "\" }";
    //Somehow get the response which is being ran on another thread (See below)

    //Process the JSON into a object and check is successful or not 
    if (msg.result == "Ok") return true;
    else return false;
}

private void ReadThread()
{
    while (running)
    {
        if (ns.DataAvailable)
        {
            string msg = reader.ReadLine();
            if (String.IsNullOrEmpty(msg)) continue;
            Process(msg); //Process the message aka get it back to the Login method
        }
    }
}

Edit 2: Basically I want to be able to call a login method which will write to a TcpClient and wait to receive a reply from the same stream and then return a boolean value.

But a basic method like so wouldn't cut it:

public bool Login(string username, string password) {
    writer.Write("{ \"username\" : \"" + username + "\", \"password\" : \"" + password + "\" }";
    string response = reader.ReadLine();
    if (response == "success") return true;
    else return false;
}

This wouldn't work because other data gets automatically pushed through the stream to me, so when waiting on the ReadLine(), I could be getting anything else instead of the response that I'm looking for.

So I'm looking for a solution which can solve this issue, currently I have a thread running which is purely for reading from the stream and then processing the message, I need to get the message from that thread over to this above method.

One way I thought about doing this is when a message gets read, for it to be put in a global List which then the Login method can be put in a loop which checks the List until the message is found within the list. But if I'm right in thinking, this is a terrible concept. So I'm looking for an alternative.

Community
  • 1
  • 1
Tom O
  • 1,780
  • 2
  • 20
  • 43
  • Can you guarantee C# 5 (.NET 4.5)? `async/await` sounds like an awesome fit for your case and it'd let you continue developing code in a synchronous way. – Benjamin Gruenbaum Jun 26 '13 at 20:23
  • Was hoping .Net 4 would be the highest I'd have to go, this would be a last resort. – Tom O Jun 26 '13 at 20:24
  • You can go .NET 4 as well by referencing the Microsoft.Bcl.Async Nuget package and using the C# 5 compiler. – jods Jun 26 '13 at 20:59
  • Async/await is available for 4.0, you just need to [download it from NuGet](http://nuget.org/packages/Microsoft.CompilerServices.AsyncTargetingPack). – Scott Chamberlain Jun 26 '13 at 21:01
  • Okay, how would I incorporate the async/await in the above example? Never used either keywords before! Thanks. – Tom O Jun 26 '13 at 21:06

1 Answers1

0

My mistake. I see that you just want to create a client. Much of the below is still relevant, particular the asynchronous read/write stuff in the linked answer. You can probably dig the relevant parts out of that. Or do a search for [TcpClient asynchronous example]. There are some good samples available.

The easiest way in .NET is to use TcpListener and BeginAcceptTcpClient to asynchronously create a connection. You can then get the network stream from the TcpClient and use BeginRead / EndRead and BeginWrite / EndWrite to do asynchronous reads and writes.

The linked topics have some good examples. There's a TCP Listener example here on SO somewhere . . .

Aha! Here it is: https://stackoverflow.com/a/6294169/56778

Community
  • 1
  • 1
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • This is similar to what I want sort of, look at my edited post for further explanation. – Tom O Jun 26 '13 at 21:05