我连接到套接字服务器以发送和接收消息。当消息进出时,一切都很好,但每隔一段时间就会失去联系。我试图抓住异常并重新连接到服务器。 它失去连接时的第一个例外:
System.IO.IOException:无法从传输连接读取数据:已建立的连接已被主机中的软件中止。 ---> System.Net.Sockets.SocketException:已建立的连接已被主机中的软件中止 在System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags) 在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)
然后当它尝试重新连接时:
System.ObjectDisposedException:无法访问已处置的对象。 对象名:'System.Net.Sockets.NetworkStream'。 在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)
我的问题是我做错了什么?什么是重新连接到服务器的最佳解决方案? 我的代码看起来像这样:
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();
}
}
}
答案 0 :(得分:1)
我认为你的异常是由于你在catch语句中进行重新初始化而引起的。
在捕获内部时,网络流仍处于打开状态。因此,当您使用相同的端口创建新的TCP客户端时,我猜它正在使用与以前相同的网络流,这是在尝试读取时锁定的。
在捕获内部,您可以尝试
this.myTcpClient.Close();
this.myTcpClient.Dispose();
this.myTcpClient = new TcpClient(host, port);
this.myStream = this.myTcpClient.GetStream();
这可能有用。但我建议不要在catch中执行此操作,因为您可能会导致另一个异常。我会说尝试阅读一些例子,因为这段代码确实存在其他答案中提到的其他问题。
答案 1 :(得分:0)
你不应该在while(true)循环中读入。更好地检查myStream.Read是否返回0字节或TCP相关异常发生,在这种情况下连接将被关闭我认为,你需要处理资源并重新连接。
在这里您可以找到安全的阅读方法 - http://www.yoda.arachsys.com/csharp/readbinary.html
答案 2 :(得分:-1)
以下是一些可能有用的代码
// 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());
}
}
}