【问题标题】:Unable to do server reconnection after disconnected in C# winform在 C# winform 中断开连接后无法重新连接服务器
【发布时间】:2016-04-03 23:26:46
【问题描述】:

我正在做一个应用程序,它要求我作为客户端连接到服务器并从服务器接收数据。当连接断开时,我需要重新连接。以下是我的代码:

   public enum MySocketState
   {
       Disconnected = 0,
       Connecting,
       Connected
   }

    private Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    private byte[] _recieveBuffer = new byte[128];

    void DataProcess()
    {
        try
        {
            if (_serverSocket == null || sockState == MySocketState.Disconnected)
            {
                Console.WriteLine("Trying to connect...");

                SetupServer();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

    private void SetupServer()
    {
        try
        {
            _serverSocket.Connect("192.168.1.11", 1000);
        }
        catch (SocketException ex)
        {
            Console.WriteLine(ex.Message);
        }

        sockState = MySocketState.Connected;
        Console.WriteLine("Server connected...");
        _serverSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);

    }

    private void ReceiveCallback(IAsyncResult AR)
    {
        try
        {
            if (_serverSocket == null)
                _serverSocket = (Socket)AR.AsyncState;

            int recieved = _serverSocket.EndReceive(AR);

            if (recieved <= 0)
            {
                CloseSocket();
                return;
            }

            byte[] recData = new byte[recieved];
            Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);
            string strData = ASCIIEncoding.ASCII.GetString(recData);
            Console.WriteLine(strData);

            //Process the data stored in recData
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            CloseSocket();
        }
        finally
        {
            try
            {
                //Start receiving again
                if (_serverSocket != null)
                    _serverSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
            }
            catch (Exception ex2)
            { }
        }
    }

    public void CloseSocket()
    {
        try
        {
            if (_serverSocket != null)
            {
                if (_serverSocket.Connected)
                    _serverSocket.Shutdown(SocketShutdown.Both);
                _serverSocket.Close();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        _serverSocket = null;
        sockState = MySocketState.Disconnected;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        DataProcess();
    }

我正在使用计时器 (timer1_tick) 来始终检测服务器是否已连接。

但是它与服务器断开连接后,无法重新连接,下面是_serverSocket.Connect("192.168.1.11", 1000)行的错误信息:

A first chance exception of type 'System.NullReferenceException' occurred in fform.exe
System.NullReferenceException: Object reference not set to an instance of an object.
at fform.Form1.SetupServer() in c:\Work\Project 2015\Form1.cs:line 143
at fform.Form1.DataProcess() in c:\Work\Project 2015\Form1.cs:line 79

你们知道为什么连接不上吗?

【问题讨论】:

    标签: c# winforms sockets tcpclient tcp-ip


    【解决方案1】:

    可能是因为您在 CloseSocket() 之后将 _serverSocket 设置为 null,并且在您尝试重新连接时没有创建新的 Socket 实例。

    public void CloseSocket()
    {
        ...
        _serverSocket = null;
        ...
    }
    

    查看错误信息中的行号

    在 c:\Work\Project 2015\Form1.cs:行中的 fform.Form1.SetupServer() 143 在 c:\Work\Project 中的 fform.Form1.DataProcess() 2015\Form1.cs:第 79 行

    重新连接时您可能应该执行以下操作:

    private void SetupServer()
    {
        try
        {
            _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Added
            _serverSocket.Connect("192.168.1.11", 1000);
        }
        ...
    }
    

    【讨论】:

    • 第 79 行引用 DataProcess() 中的 SetupServer() 行。第 143 行指的是我在问题中提到的 _serverSocket.Connect("192.168.1.11", 1000)。
    • 正是我所怀疑的:)
    • 我明白了。好,谢谢!有用!但是,这些编码是连接和重新连接到服务器的最佳方式吗?我通过使用 BeginConnect() 在stackoverflow.com/questions/34521688/… 中以另一种方式执行此操作,但有问题。哪个是最好的方法?在这个问题或 BeginConnect() 中使用直接连接?
    • 您应该使用 socket.Connect() 后跟 socket.BeginReceive()。 socket.BeginConnect() 将在另一个线程中连接,因此 socket.BeginReceive() 可能在套接字连接之前开始接收消息,这是一个问题。
    猜你喜欢
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    相关资源
    最近更新 更多