Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重新连接TCPClient会引发异常_C#_.net_Wpf_Sockets_Tcp - Fatal编程技术网

C# 重新连接TCPClient会引发异常

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

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大小)

我的问题是我做错了什么?什么是重新连接到服务器的最佳解决方案? 我的代码如下所示:

  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();