C# 重新连接TCPClient会引发异常
Im连接到套接字服务器以发送和接收消息。当信息进出时,一切正常,但偶尔会失去联系。我正在尝试捕获异常并重新连接到服务器。 断开连接时的第一个异常: System.IO.IOException:无法从传输连接读取数据:已建立的连接被主机中的软件中止。-->System.Net.Sockets.SocketException:主机中的软件中止了已建立的连接 位于System.Net.Sockets.Socket.Receive(字节[]缓冲区、Int32偏移量、Int32大小、SocketFlags和SocketFlags) 位于System.Net.Sockets.NetworkStream.Read(字节[]缓冲区,Int32偏移量,Int32大小) 然后当它尝试重新连接时: System.ObjectDisposedException:无法访问已处置的对象。 对象名称:“System.Net.Sockets.NetworkStream”。 位于System.Net.Sockets.NetworkStream.Read(字节[]缓冲区,Int32偏移量,Int32大小) 我的问题是我做错了什么?什么是重新连接到服务器的最佳解决方案? 我的代码如下所示:C# 重新连接TCPClient会引发异常,c#,.net,wpf,sockets,tcp,C#,.net,Wpf,Sockets,Tcp,Im连接到套接字服务器以发送和接收消息。当信息进出时,一切正常,但偶尔会失去联系。我正在尝试捕获异常并重新连接到服务器。 断开连接时的第一个异常: System.IO.IOException:无法从传输连接读取数据:已建立的连接被主机中的软件中止。-->System.Net.Sockets.SocketException:主机中的软件中止了已建立的连接 位于System.Net.Sockets.Socket.Receive(字节[]缓冲区、Int32偏移量、Int32大小、SocketFlags
class Test
{
private TcpClient myTcpClient;
private NetworkStream myStream;
private string host = xxx.xxx.xxx;
private int port = 8888;
private string streaming = "";
public void Listen()
{
this.myTcpClient = new TcpClient(host, port);
this.myStream = this.myTcpClient.GetStream();
Listener();
}
private void Listener()
{
try
{
while (true)
{
byte[] numResponse = new byte[8192];
int x = this.myStream.Read(numResponse, 0, numResponse.Length);
Decrypt(numResponse, 0, x);
string stream = Encoding.UTF8.GetString(numResponse);
this.streaming = string.Concat(this.streaming, stream);
}
}
catch(Excpetion ex)
{
// write ex.ToString() to TextFile
this.myTcpClient = new TcpClient(host, port);
this.myStream = this.myTcpClient.GetStream();
Listener();
}
}
}
您不应该读入while(true)循环。最好检查myStream.Read是否返回0字节或是否发生TCP相关异常,在这种情况下,连接将被关闭。我认为,您需要处理资源并重新连接
在这里您可以找到安全的阅读方法-这里有一些代码可能会有所帮助
// State object for receiving data from remote device.
public class StateObject
{
/// <summary>
/// Client socket.
/// </summary>
public Socket workSocket = null;
/// <summary>
/// Size of receive buffer.
/// </summary>
public const int BufferSize = 256;
/// <summary>
/// Receive buffer.
/// </summary>
public byte[] buffer = new byte[BufferSize];
/// <summary>
/// Received data string.
/// </summary>
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int _port = xxxx;
private const string _address = "xx.xx.xx.xx";
// ManualResetEvent instances signal completion.
private static ManualResetEvent _connectDone = new ManualResetEvent(false);
private static ManualResetEvent _sendDone = new ManualResetEvent(false);
private static ManualResetEvent _receiveDone = new ManualResetEvent(false);
private static string _response = string.Empty;
public static void StartClient(string data)
{
// Connect to a remote device.
try
{
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(_address, _port, ConnectCallback, client);
_connectDone.WaitOne();
// Send test data to the remote device.
//Console.WriteLine("Sending data : {0}", data);
Send(client, "US\r\n");
_sendDone.WaitOne();
Thread.Sleep(1000);
Send(client, data);
_sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
_receiveDone.WaitOne();
// Write the response to the console.
//Console.WriteLine("Response received : {0}", _response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
var client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
_connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
var state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
var state = (StateObject)ar.AsyncState;
var client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1) _response = state.sb.ToString();
_receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, String data)
{
var byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
var bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
_sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
//用于从远程设备接收数据的状态对象。
公共类状态对象
{
///
///客户端套接字。
///
公共套接字工作组=null;
///
///接收缓冲区的大小。
///
public const int BufferSize=256;
///
///接收缓冲区。
///
公共字节[]缓冲区=新字节[BufferSize];
///
///接收到的数据字符串。
///
公共StringBuilder sb=新StringBuilder();
}
公共类异步客户端
{
//远程设备的端口号。
专用const int_port=xxxx;
私有常量字符串_address=“xx.xx.xx.xx”;
//ManualResetEvent实例信号完成。
专用静态手动复位事件_connectDone=新手动复位事件(假);
专用静态手动复位事件_sendDone=新手动复位事件(假);
专用静态手动复位事件_receiveDone=新手动复位事件(假);
私有静态字符串_response=string.Empty;
公共静态void StartClient(字符串数据)
{
//连接到远程设备。
尝试
{
var client=newsocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//连接到远程端点。
BeginConnect(_地址,_端口,ConnectCallback,客户端);
_connectDone.WaitOne();
//将测试数据发送到远程设备。
//WriteLine(“发送数据:{0}”,数据);
发送(客户端,“美国”\r\n);
_sendDone.WaitOne();
睡眠(1000);
发送(客户端、数据);
_sendDone.WaitOne();
//从远程设备接收响应。
接收(客户);
_receiveDone.WaitOne();
//将响应写入控制台。
//WriteLine(“收到的响应:{0}”,_响应);
//松开插座。
client.Shutdown(SocketShutdown.Both);
client.Close();
}
捕获(例外e)
{
Console.WriteLine(如ToString());
}
}
专用静态无效连接回调(IAsyncResult ar)
{
尝试
{
//从状态对象检索套接字。
var client=(Socket)ar.AsyncState;
//完成连接。
客户端.EndConnect(ar);
WriteLine(“连接到{0}的套接字”,client.RemoteEndPoint.ToString());
//表示已建立连接的信号。
_connectDone.Set();
}
捕获(例外e)
{
Console.WriteLine(如ToString());
}
}
私有静态void接收(套接字客户端)
{
尝试
{
//创建状态对象。
var state=newstateObject();
state.workSocket=客户端;
//开始从远程设备接收数据。
BeginReceive(state.buffer,0,StateObject.BufferSize,0,ReceiveCallback,state);
}
捕获(例外e)
{
Console.WriteLine(如ToString());
}
}
私有静态void ReceiveCallback(IAsyncResult ar)
{
尝试
{
//检索状态对象和客户端套接字
//从异步状态对象。
var state=(StateObject)ar.AsyncState;
var client=state.workSocket;
int bytesRead=client.EndReceive(ar);
如果(字节读取>0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
BeginReceive(state.buffer,0,StateObject.BufferSize,0,ReceiveCallback,state);
}
其他的
{
//所有数据都已到达,请将其作为响应。
如果(state.sb.Length>1)_response=state.sb.ToString();
_receiveDone.Set();
}
}
捕获(例外e)
{
Console.WriteLine(如ToString());
}
}
私有静态void发送(套接字客户端、字符串数据)
{
var byteData=Encoding.ASCII.GetBytes(数据);
BeginSend(byteData,0,byteData.Length,0,SendCallback,client);
}
私有静态void SendCallback(IAsyncResult ar)
{
尝试
{
var client=(Socket)ar.AsyncState;
var bytesent=client.EndSend(ar);
控制台写入线
this.myTcpClient.Close();
this.myTcpClient.Dispose();
this.myTcpClient = new TcpClient(host, port);
this.myStream = this.myTcpClient.GetStream();