断开连接后如何重新使用或重新连接到同一端口上的套接字?

时间:2014-07-23 23:35:25

标签: c# sockets tcp client-server port

我正在做一个涉及单个服务器程序和单个客户端程序的简单项目。它需要检查客户端是否已连接(从服务器端),反之亦然。

当客户端丢失互联网时,服务器需要知道它已断开连接。然后,客户端需要在重新获得互联网时重新连接到服务器

当客户端丢失互联网然后重新上网时,我无法使用相同的端口重新连接。

我尝试让服务器监听,而不是关闭套接字,这也不起作用。我已经在重新使用方面为插座尝试了很多属性,而且我也试过了挥之不去的东西。

我已经看到它可能卡在注册表中操作系统设置的某些TIME_WAIT属性上(在Windows的情况下)。我要回答的问题是,在客户端丢失并重新获得互联网并仍然在等待重新连接之后,能够使用相同的套接字(更重要的是相同的端口)重新连接。

就像我说的那样,我可以检测到它与服务器端以及客户端断开连接但是当我尝试使用相同的端口重新连接并使用相同的套接字或重新启动的套接字时,它仍然无法连接并且它根本不会出现。有什么建议可以帮助解决这个问题吗?我一直在寻找很长一段时间来解决这个问题。

情景:

  1. 服务器正在倾听
  2. 客户端连接到服务器
  3. 从互联网上拔下客户端
  4. 将客户端网络电缆重新插入
  5. 客户端自动重新连接到服务器(目前不在同一端口上执行此操作)
  6. TL; DR在客户端 - 服务器模型上丢失并重新获得互联网,但不能使用相同的套接字和端口连接到服务器。

    CODE:

        private void button2_Click(object sender, EventArgs e)
        {
    
            // This will stop the threads/connections and toggle the button back to its original state
            if (button2.Text == "Stop Listening")
            {
    
                listener.Close();
                stop = true;
                threadsActive = false;
                button2.Text = "Start Listening";
                textBox1.AppendText("Manually Closed Threads/Connections" + Environment.NewLine);
    
            }
            else
            {
    
                listenThread = new Thread(listenLoop);
                listenThread.IsBackground = true;
                status = new Thread(checkIfOnline);
                status.IsBackground = true;
                stop = false;
                threadsActive = true;
                button2.Text = "Stop Listening";
                localEndPoint = new IPEndPoint(IPAddress.Parse("129.59.79.65"), 3000);
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listenThread.Start();
                status.Start();
    
            }
    
        }
    

    =============================================== =====

    private void listenLoop()
        {
    
            try
            {
    
                listener.Bind(localEndPoint);
                listener.Listen(100);
    
                textBox1.AppendText("Waiting for a client..." + Environment.NewLine);
    
                listener = listener.Accept();
                textBox1.AppendText("Client Connected!!" + Environment.NewLine);
    
                status.Start();
    
                while (!close)
                {
    
                    if (stop)
                        return;
                    // server connection loop
    
                }
    
                if(close)
                    return;
    
            }
            catch (Exception excp)
            {
    
    
    
            }
    
        }
    

    =============================================== =====

    private void ResetSocket()
        {
    
            // stop all threads and connections
            stop = true;
            listener.Close();
    
            textBox1.AppendText("Attempting to kill threads..." + Environment.NewLine);
            //while (listenThread.IsAlive == true || status.IsAlive == true) { /*loop until the threads are killed*/ textBox1.AppendText("Closing Threads..."); }
            //listener.Close();
            threadsActive = false;
    
            textBox1.AppendText("All Threads/Connections Closed" + Environment.NewLine + "Restarting Threads/Connections..." + Environment.NewLine);
    
            // re-establish and start threads and connections again
            stop = false;
            listenThread = new Thread(listenLoop);
            listenThread.IsBackground = true;
            status = new Thread(checkIfOnline);
            status.IsBackground = true;
            threadsActive = true;
            localEndPoint = new IPEndPoint(IPAddress.Parse("129.59.79.65"), 3000);
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listenThread.Start();
            status.Start();
    
            textBox1.AppendText("Threads/Connections Restarted Successfully" + Environment.NewLine);
    
        }
    

2 个答案:

答案 0 :(得分:2)

不要绑定客户端套接字。只有服务器端口很重要。

在服务器端,只需保持侦听套接字监听。当侦听套接字接受连接时,它将返回表示该连接的 new 套接字。当您检测到连接丢失时,请关闭相应的连接套接字,但保持侦听套接字正在运行。

另一方面,IMO检测连接丢失的最佳方法是定期发送数据(双向)。

我的博客上有TCP/IP .NET FAQ。它是.NET,但一般概念适用于任何TCP / IP场景。

答案 1 :(得分:0)

详细阐述斯蒂芬克莱里的极好答案。在我们创建并绑定它之后,服务器开始监听。控制进入无限循环。客户端连接到服务器。如果我们现在拔掉Internet,客户端会抛出一个异常,它将我们返回到无限循环的顶部,我们在尝试接受另一个连接之前等待网络连接。

ID Date Interval_mins Total_mins
10 4/1/16  60              80
10 4/1/16  20              80
20 4/1/16  60              85