TCP连接C#中套接字的正确初始化和配置

问题描述 投票:0回答:1

我对以下代码有疑问:

    private static readonly Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static readonly List<Socket> clientSockets = new List<Socket>();
        private const int BUFFER_SIZE = 1024*2;
        private static readonly byte[] buffer = new byte[BUFFER_SIZE];
        public static Manager Manager { get; set; }
        private static bool firstInit = true;

        /// <summary>
        /// Config and start the server
        /// </summary>
        public static void SetupServer()
        {
            try
            {
                Manager.PCForm.ConnectionButtonStatus(false);
                var PORT = int.Parse(Properties.Settings.Default.LocalPort);
                var listenToAny = Properties.Settings.Default.ListenToAny;
                var IP = GetSocketIP(listenToAny);

                Logger.LogInfo("Setting up server...");

                if(Properties.Settings.Default.UseLocalWifiNetwork)
                {
                    Logger.LogInfo("PC Local IP: " + LocalIPAddress);
                }
                else
                {
                    Logger.LogInfo("PC External IP: " + ExternalIPAddress);
                }           

                if(firstInit)
                {
                    firstInit = false;
                    Logger.LogDebug("Binding new port:" + PORT);
                    serverSocket.Bind(new IPEndPoint(IP, PORT));
                }
                else
                {
                    Logger.LogDebug("Using port that was already binded");
                }

                serverSocket.Listen(0);
                Logger.LogDebug("Listening To: " + IP + ":" + PORT);
                serverSocket.BeginAccept(AcceptCallback, null);
                Manager.PCForm.ConnectionButtonStatus(true);
                Logger.LogInfo("Server setup complete");
            }
            catch(Exception ex)
            {
                FormsHelpers.ShowErrorMessage(ex.Message);
                Logger.LogError("Fail to setup server. Please restart the app.");
            }
        }

   public static void CloseAllSockets()
        {
            try
            {
                Logger.LogDebug("Closing All Sockets...");
                Manager.PCForm.ConnectionButtonStatus(false);
                foreach(Socket socket in clientSockets.ToArray())
                {
                    CloseSocket(socket);
                }

                serverSocket.Close();
                Logger.LogInfo("Server was shutdown");
                Manager.PCForm.ConnectionButtonStatus(true);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Fail to close sockets.\r\nExpection: " + ex.Message);
            }
        }

当我想重用绑定的套接字时,我的问题开始了。我的应用程序支持关闭并重新打开服务器中的TCP连接(可以是同一端口,也可以是新端口)。

场景:

1。用户启动服务器(在本地IP和端口5000中打开TCP套接字。

2。用户停止服务器(服务器关闭客户端TCP连接和服务器套接字)

3。用户再次启动服务器(相同端口-5000或新端口,如果用户在应用程序设置中更改了端口)。

[当用户使用相同的端口(5000)再次启动服务器时,出现错误:无法访问已处置的对象!当用户使用新端口(5001)再次启动服务器时,出现错误:无效参数(因为服务器套接字已绑定到其他端口)。

如果删除代码serverSocket.Close();,它将起作用,因为服务器套接字从未关闭,因此无需更改端口即可。在这种情况下,请查看netstat:

enter image description here

但是这不好,因为除非保存了配置并且用户重新启动了应用程序,否则不允许更改端口。

c# tcp serversocket tcpserver
1个回答
0
投票

我更新了代码。当我关闭服务器时,我仅断开客户端连接。当我启动服务器时,我会重用最后一个套接字,但是如果更改端口,我将关闭它并分配一个新的socketServer实例并使用它。

  if(portInUse.Equals(PORT))
                {
                    Logger.LogDebug("Using port that was already binded");
                }
                else
                {
                    Logger.LogDebug("Binding new port:" + PORT);

                    if(serverSocket != null)
                    {
                        //close previous socket because it was using old port
                        serverSocket.Close();
                    }

                    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    serverSocket.Bind(new IPEndPoint(IP, PORT));
                    portInUse = PORT;
                }
© www.soinside.com 2019 - 2024. All rights reserved.