4

Im trying to connect to my router inside local network. I've used the TcpClient so far.

Check my code:

public static void RouterConnect()
        {    
            TcpClient tcpClient = new TcpClient("192.168.180.1",23); <-- Timeout comes up here
            tcpClient.ReceiveTimeout = 2000; // Not working
            tcpClient.SendTimeout = 2000; // Also not working
            NetworkStream nStream = tcpClient.GetStream(); <-- thought Timeout would raise here

            // Further code here. But already tested while commented out. 
            // So everything else expect the code above shouldnt be relevant.
        }

I would like to add a settings-form (router-ip/user/password). Therefore there could be a fail on the user-side where the user types in a not existing host-ip.

The current timeout is at about 20 seconds which is way too high. TcpClient.ReceiveTimeout and TcpClient.SendTimeout arnt the right timeouts to set as I already tried it. Google wasnt helping me out with this.

So, anyone knows how to set the timeout in the right way for this? I've read about async. connections which I wouldnt like to use. A cleaner 1-line-timeout-set would be nice. Possible?

Thanks very much!

Edit 1: With a closer look while debugging I noticed, the timeout is already raising at the initialization of the tcpClient (as edited above in my code) not as I thought before at .GetStream().


EDIT SOLUTION:

As no one posted the working code from the solution I picked, here it is how its working:

public static void RouterConnect()
        {
            TcpClient tcpClient = new TcpClient();
            if(tcpClient.ConnectAsync("192.168.80.1",23).Wait(TimeSpan.FromSeconds(2)))
            {
                NetworkStream nStream = tcpClient.GetStream();
            }
            else
            {
                MessageBox.Show("Could not connect!");
            }
        }
C4d
  • 3,183
  • 4
  • 29
  • 50
  • Where are you reading from the stream? – cbr Jul 15 '15 at 18:35
  • It comes later but isnt relevant I guess. I commented out the reading. The timeout comes as seen in my edited code above at the initialization of the tcpClient. – C4d Jul 15 '15 at 18:37
  • 1
    That constructor of `TcpClient` also [connects the client](https://msdn.microsoft.com/en-us/library/115ytk56(v=vs.110).aspx) to the endpoint. – cbr Jul 15 '15 at 18:39
  • @cubrr Yeah thanks. Just noticed that about 5 minutes before. Anyway, my question stays the same. – C4d Jul 15 '15 at 18:40
  • 1
    I suppose your question is similar to [this one](http://stackoverflow.com/questions/17118632/how-to-set-the-timeout-for-a-tcpclient). If you're targeting .NET 4.5, [this answer](http://stackoverflow.com/a/30917334/996081) might do the trick. – cbr Jul 15 '15 at 18:42
  • Yeah async. connection. As told above I hoped getting around it. Looks like I have no chance going another way. – C4d Jul 15 '15 at 18:46
  • Internally, `WSAConnect` is used to connect the socket. I didn't find anything that would suggest that the socket's connection timeout can be altered. – cbr Jul 15 '15 at 18:49
  • @C4ud3x, Edited my answer. – Orel Eraki Jul 15 '15 at 18:52
  • As my solution isnt posted below I'll edit (append) my solution into my question and mark the closest answer. Thanks to you guys! – C4d Jul 15 '15 at 18:55
  • @cubrr Thanks to you too. Followed your commented answer (4.5...). – C4d Jul 15 '15 at 18:59
  • @C4ud3x You can (and should) post your solution as an answer yourself and accept it if it...solved your question :) – cbr Jul 15 '15 at 19:01
  • @cubrr Yeah normally yes. But `Or Harambam` went into the right direction with his answer AND come on.. his reputation... thought I would rather go this way and give him his tick mark ;). – C4d Jul 15 '15 at 19:20

3 Answers3

1

The only way i know is to use the Async methods. There is a nice new async method in .Net 4.5 which returns a Task that you could Wait like this:

tcpClient.ConnectAsync().Wait(timeout)

It returns a false if it doesn't succeed.

  • Ill check it out. Its quite the same as cubrr noticed in the comments under my question. – C4d Jul 15 '15 at 18:49
0

Yeah the cleanest way I suppose would be to use the TcpClient.BeginConnect method.

So you would have a asynchronous feedback whether you could connect to the endpoint or not. Also see this: Async Connect

darkfirewave
  • 82
  • 1
  • 7
  • Regarding your Edit: Yeah the onstructor also call connect. As an alternative you could call the empty constructor and then use Connect or BeginConnect – darkfirewave Jul 15 '15 at 18:41
0

The current constructor overloading method your using is also connecting and thus blocking you until it get connected.

Furthermore, There are no properties on TcpClient to control the TcpClient timeout.

From MSDN: TcpClient(String, Int32)

Initializes a new instance of the TcpClient class and connects to the specified port on the specified host.

Alternative code from Social MSDN

using (vartcp = new TcpClient())  
{  
    IAsyncResult ar = tcp.BeginConnect("192.168.180.1", 23, null, null);  
    System.Threading.WaitHandle wh = ar.AsyncWaitHandle;  
    try 
    {  
       if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2), false))  
       {  
           tcp.Close();  
           throw new TimeoutException();  
       }  

        tcp.EndConnect(ar);  
    }  
    finally 
    {  
        wh.Close();  
    }  
} 
Orel Eraki
  • 11,940
  • 3
  • 28
  • 36