问题
My Tcpclient did not disconnect properly I am using Client async.
I want to reconnect again automatic when server disconnect.
What is correct path?
This is Connection code
private void Connect_btn_Click(object sender, EventArgs e)
{
try
{
if (IsConnected == false)
{
constatus.Text = "Connecting.....";
newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//IPEndPoint iep = new IPEndPoint(IPAddress.Any, 20);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(IP), Convert.ToInt16(PORT));
newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
}
else
{
MessageBox.Show("Connection is Already Connected");
}
}
catch (Exception)
{
MessageBox.Show("Please Enter IPAddress and Port Address","Error",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
}
//This is Connected Function IASYNCHRESLT interface using call back
//Connected Function Call Back Asynch use in Connection button
void Connected(IAsyncResult iar)
{All Commands Inputs Send Fucntion Calling}
{
try
{
client = (Socket)iar.AsyncState;
client.EndConnect(iar);
this.Invoke(new viewStatus(setValue), "Connected");
//constatus.Text = "Connected To:" + client.RemoteEndPoint.ToString();
client.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), client);
GetAllDateHide_performClick();
}
catch (SocketException)
{
ErrorConnecting();
}
}
this is disconnect code
private void ButtonDisconnect_Click(object sender, EventArgs e)
{
try
{
client.Close();
constatus.Text = "Disconnected";
}
catch (Exception) { }
}
and how to handle the ObjectDisposed Exception i will disconnect
回答1:
First, I'm not sure why you're using a socket directly instead of using a TcpClient (documentation). Is there a reason? because TcpClient is cleaner.
Second, if you're already planning for asynchrony why not use async-await?
Lastly, I won't recommend doing network operations directly from the GUI.
About the automatic reconnection i see 2 options.
- Reconnecting if an operation resulted in an error.
- Having a backward worker trying every once in a while to reconnect.
You haven't showed any operations so I present my take on the second one:
public class TcpManager
{
private TcpClient _tcpClient;
public TcpManager()
{
_tcpClient = new TcpClient(AddressFamily.InterNetwork);
Task.Run(() => ConnectAsync());
}
private async Task ConnectAsync()
{
while (true)
{
if (!_tcpClient.Connected)
{
Console.WriteLine("Connecting...");
try
{
_tcpClient = new TcpClient(AddressFamily.InterNetwork);
await _tcpClient.ConnectAsync(IPAddress.Parse(IP), Convert.ToInt16(PORT));
await Task.Delay(TimeSpan.FromSeconds(5));
}
catch (SocketException e)
{
Console.WriteLine(e);
}
}
else
{
Console.WriteLine("Already Connected");
}
}
}
private void Close()
{
try
{
_tcpClient.Close();
_tcpClient = new TcpClient(AddressFamily.InterNetwork);
Console.WriteLine("Disconnected");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
回答2:
As the answer above, you should use TCP client. Do not use socket ditectly in application layer.
But even when TCP client is used and you've got a lot of properties, still comes the problem. That is because TCP/IP protocol force the port in TIME_WAIT status. That's for some reasons, which is another topic. OK, now the port you use must wait for 140 seconds during that period, you cannot use this port(which means ipend in .net).There are two ways to deal with this annoying TIME_WAIT status.
- Try to use UDP protocol instead of TCP/IP, cause it's Connection-oriented.
- Change the port number, establish another connection if you insist using TCP/IP protocols.
来源:https://stackoverflow.com/questions/20870641/reconnect-to-the-server