Порт застрял в Time_Wait - PullRequest
4 голосов
/ 08 апреля 2011

У меня есть TCP-туннель в C #.Мне нужно открыть и закрыть туннель, который является моим приложением между сервером и клиентом.Я использую это, чтобы закрыть соединение для передачи данных, чтобы проверить другое приложение.Я должен использовать определенные порты.

На втором, третьем, n-м соединении, в зависимости от того, как долго я жду, чтобы восстановить соединение, я получаю код ошибки 10048 - «Адрес уже используется» при привязке моего сокета.При закрытии сокетов я выполняю ShutDown.Both и Close в надежде очистить порты, но когда я выполняю netstat в командной строке, я все еще нахожу порты, содержащиеся в TIME_WAIT.Я также установил розетки, чтобы не задерживаться.Наконец, я попытался сделать цикл, чтобы проверить состояние порта, но он заканчивается несколько бесконечным циклом.Я думаю, что это правило 4 минуты TIME_WAIT.

У меня есть функция для отображения запроса Nestat, и я обнаружил, что когда я запускаю его и проверяю, пока порт не переходит из ESTABLISHED в TIME_WAIT, который я могу связать, но когда я использую те же данные из этого запроса дляПри связывании в цикле, когда статус достигает TIME_WAIT, я получаю 10048. Есть ли краткий момент времени, позволенный моим нажатием кнопки, который позволяет мне связываться?Есть ли между TIME_WAIT и ESTABLISHED состояние, в которое я попадаю в цикле, а не при нажатии кнопки?Я прочитал, что TIME_WAIT должен полностью остановить меня от привязки, но это не похоже на правду.Кто-нибудь может объяснить это?

Я извиняюсь перед любителями кода.Не думая, что это что-то изменит, хотя.Мне просто нужно лучшее понимание состояний портов.

    public bool CheckAvailablePorts()
    {
        int temp=0;
        bool availPort= true;
        m_config = new AppConfig();
        if (!m_config.initialize())
        {
            System.Diagnostics.Debug.WriteLine("Error loading configuration file.  Exiting...");
            return false;
        }
        else
        {

//checking through all the ports that have been set to connect on

            foreach (ProxyConfig cfg in m_config.m_proxyConfigs)
            {
                availPort = true;
                temp = cfg.localEP.Port;
                DataView dv = FindEstablishedSockets();//returns netstat query
                foreach (DataRowView rowView in dv)
                {
                    DataRow row = rowView.Row;

                    if ((Convert.ToInt32(row["Local Port"].ToString()) == temp) && (row["Status"].ToString().Equals("Established")))
                    {
                        System.Diagnostics.Debug.WriteLine("Port: " + temp + " is still locked");
                        availPort = false;
                        break;
                    }
                }
            }
            return availPort;
        }
    }

//snippet out of a bigger function which checks for availability and then sleeps if false and runs again

            bool temp = false;
            while (!temp)
            {
                temp = monitor.CheckAvailablePorts();
                System.Threading.Thread.Sleep(2000);
            }
            System.Threading.Thread.Sleep(3000);
            monitor.startApplication(); //starts all the binding

Ответы [ 3 ]

0 голосов
/ 20 апреля 2011

Я прочитал, что TIME_WAIT должен полностью остановить меня от привязки, но это не похоже на правду.

Существует опция, которую вы можете использовать, которая позволит вам привязать локальный порт, который находится в TIME_WAIT. Это очень полезно для гарантии того, что вам не придется ждать 4 минуты после уничтожения сервера перед его перезапуском.

int flag = 1;
sockfd = socket(...);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
bind(...);
0 голосов
/ 02 февраля 2012

Перед закрытием сокета вы должны прочитать все данные, отправленные его партнером, в противном случае он останется в TIME_WAIT, чтобы новый сокет не считывал данные, предназначенные для предыдущего (закрытого).Вы также можете попробовать опцию «без затягивания сокета».

Подробности: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx

0 голосов
/ 08 апреля 2011

Вы должны быть немного конкретнее, так как трудно понять, что вы делаете.Более короткий текст и пример кода помогут.

Мне нужно открывать и закрывать соединения, а затем снова открывать их

Это не должно быть проблемой, если оно в клиенте,Если это на стороне сервера, объясните, почему.

Файл конфигурации на сервере ищет определенный порт, поэтому при повторном подключении мне нужно снова открыть тот же порт

Что ты имеешь в виду?Если вы имеете в виду порт прослушивания: вы никогда не должны закрывать сокет слушателя.Если вы не хотите принимать более одного сокета, просто не вызывайте Accept снова, пока клиентский сокет не будет отключен.

...