C # How to stop the tcpClient.Connect () process when I am ready to complete the program? He just sits there like 10 seconds!

This is one of my first questions. Whenever I exit the program, tcpClient.Connect () closes forever. I tried a ton of things and none of them seem to work.

Take a look at the CreateConnection () stream if the client is not already connected ... and I close the program and it closes forever. If it is connected, it closes immediately. I know this can be done with some sort of timeout trick, but I tried several and none of them worked.

Please provide an example code if you can.

Also, is there a good tutorial for C # when reading / writing actual bytes with a buffer instead of this version that just does masterServer.writeLine () and masterServer.readline (), or are they both effective?

If you see anything else to help me improve this ... by all means, go on. I'm trying to teach myself how to do this, and I have no help, so don't let me do something wrong if you see it! Thanks guys!

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; using System.IO; namespace RemoteClient { public partial class Form1 : Form { private int MyPort = 56789; private IPAddress myIp = IPAddress.Parse("210.232.115.79"); private IPAddress serverIp = IPAddress.Parse("72.216.18.77"); // Master Server IP Address public static TcpClient masterServer = new TcpClient(); private StreamWriter responseWriter; private StreamReader commandReader; private Thread connectionThread; private Thread commandsThread; private bool RequestExitConnectionThread { get; set; } private delegate void AddMessageDelegate(string message, int category); private delegate void ConnectedDelegate(); private bool isConnected { get; set; } public Form1() { InitializeComponent(); isConnected = false; } private void LogMessage(string message, int category) { if (category == 1) { ListViewItem item = new ListViewItem(message); item.BackColor = Color.LightGreen; item.UseItemStyleForSubItems = true; Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString()); } if (category == 2) { ListViewItem item = new ListViewItem(message); item.BackColor = Color.Orange; item.UseItemStyleForSubItems = true; Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString()); } if (category == 3) { ListViewItem item = new ListViewItem(message); item.BackColor = Color.Yellow; item.UseItemStyleForSubItems = true; Log.Items.Add(item).SubItems.Add(DateTime.Now.ToString()); } if (category == 0) { Log.Items.Add(message).SubItems.Add(DateTime.Now.ToString()); } } private void Connected() { LogMessage("Found and Accepted Master Server connection. Waiting for reply...",1); Status.Text = "Connected!"; Status.ForeColor = Color.Green; commandsThread = new Thread(new ThreadStart(RecieveCommands)); sendClientInfo(); } private void exitButton_Click(object sender, EventArgs e) { Disconnect(); exitButton.Enabled = false; exitButton.Text = "Closing..."; if (connectionThread != null) { while (connectionThread.IsAlive) { Application.DoEvents(); } } this.Close(); } private void Form1_Load(object sender, EventArgs e) { Connect(); } private void Disconnect() { RequestExitConnectionThread = true; if (masterServer != null) masterServer.Close(); if (connectionThread != null) connectionThread.Abort(); LogMessage("Closing Client. Please wait while Program threads end.", 2); } private void Disconnected() { Status.Text = "Disconnected"; Status.ForeColor = Color.Red; Connect(); } private void Connect() { LogMessage("Attempting to connect to Master Server...", 1); connectionThread = new Thread(new ThreadStart(CreateConnection)); connectionThread.Start(); } private void CreateConnection() { int i = 1; bool success = false; while (!success) { try { using (masterServer = new TcpClient()) { IAsyncResult result = masterServer.BeginConnect(serverIp, MyPort, null, null); success = result.AsyncWaitHandle.WaitOne(1000, false); } if (success) { BeginInvoke(new ConnectedDelegate(this.Connected), new object[] {}); break; } else { Thread.Sleep(2000); BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connection Retry # " + i.ToString() + ". Master Server hasn't been started yet.", 3 }); } } catch { MessageBox.Show("Error!"); } i++; } } private void RecieveCommands() { MessageBox.Show("Hello!"); commandReader = new StreamReader(masterServer.GetStream()); string CommandResponse = commandReader.ReadLine(); string Command = null; if (CommandResponse != null) MessageBox.Show("Recieved Command that was NOT null!"); if (CommandResponse != null) { MessageBox.Show("Recieved null response!"); BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: Recieved Null response.", 1 }); Disconnected(); } else if (CommandResponse.StartsWith("0")) { MessageBox.Show("Recieved 0 as a response!"); Command = CommandResponse.Substring(2).Trim(); isConnected = false; BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Disconnected From Master Server. Reason: " + Command, 1 }); } else if (CommandResponse.StartsWith("1")) { MessageBox.Show("Recieved 1 as a response!"); isConnected = true; BeginInvoke(new AddMessageDelegate(LogMessage), new object[] { "Connected to Master Server Successfully.", 1 }); } } //************************** RESPONSE BELOW HERE ************************* \\ private void sendClientInfo() { responseWriter = new StreamWriter(masterServer.GetStream()); responseWriter.WriteLine(myIp.ToString()); responseWriter.Flush(); } } } 
+4
source share
3 answers

Adding a test to the connection process to cancel it, if the program exits, should help.

Try adding this to CreateConnection() inside the while(!success) , but before the try block:

 if(RequestExitConnectionThread) { break; } 

Here is an example of an asynchronous call to BeginConnect ():

 myTcpClient.BeginConnect("localhost", 80, OnConnect, null); 

OnConnect Function:

 public static void OnConnect(IAsyncResult ar) { // do your work } 
+1
source

Sorry, after testing: no, it does not use asynchronous waithandle, it blocks the process: (

I prefer this solution, which also blocks the process, but only for the period you specified, in this case 5 seconds:

 using (TcpClient tcp = new TcpClient()) { IAsyncResult ar = tcp.BeginConnect("127.0.0.1", 80, null, null); System.Threading.WaitHandle wh = ar.AsyncWaitHandle; try { if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false)) { tcp.Close(); throw new TimeoutException(); } tcp.EndConnect(ar); } finally { wh.Close(); } } 

From: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/2281199d-cd28-4b5c-95dc-5a888a6da30d

The following example uses both an asynchronous connection and an asynchronous timeout:

 var tcp = new TcpClient(); var ar = tcp.BeginConnect(Ip, Port, null, null); Task.Factory.StartNew(() => { var wh = ar.AsyncWaitHandle; try { if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false)) { // The logic to control when the connection timed out tcp.Close(); throw new TimeoutException(); } else { // The logic to control when the connection succeed. tcp.EndConnect(ar); } } finally { wh.Close(); } }); 
+8
source

2000 ms connection timeout:

 AutoResetEvent connectDone = new AutoResetEvent( false ); TcpClient client = new TcpClient(); client.BeginConnect( "127.0.0.1", 80, new AsyncCallback( delegate( IAsyncResult ar ) { client.EndConnect( ar ); connectDone.Set(); } ), client ); if( !connectDone.WaitOne( 2000 ) ) { Console.WriteLine( "network connection failed!" ); Environment.Exit( 0 ); } Stream stream = client.GetStream(); 
+5
source

All Articles