Управление Winsock VB6: закрытие соединения и подключение к другому серверу - PullRequest
3 голосов
/ 15 июня 2011

Я работаю над устаревшим приложением VB6. Приложение использует RAS API для установления модемного соединения, затем использует элемент управления winsock для подключения к IP-адресу и порту.

Я сейчас добавляю функцию «аварийного переключения» в это приложение, где, если он не может подключиться к серверу, он пытается подключиться к следующему в списке.

Допустим, у меня есть два сервера, серверное приложение A и серверное приложение B. (Во время моих тестов я поменял их местами, чтобы убедиться, что оба сервера доступны и нет проблем с маршрутизацией / брандмауэром.)

Если я остановлю серверное приложение A, то произойдет нечто странное, когда приложение попытается подключиться к серверному приложению A, а затем к серверному приложению B:

mySocket.close
mySocket.Connect serverA, portA
  • mySocket.state = 6 sckConnecting
  • событие подключения к сокету называется
  • mySocket.state = 7 sckConnected
  • mySocket.state = 8 sckClosing

(что немного странно: я не уверен, почему он подключается на несколько мгновений.)

Сокет остается в состоянии sckClosing. Через несколько сотен миллисекунд я перехожу к попытке подключиться к серверу B:

mySocket.close
  • mySocket.state = 0 sckClosed

.

mySocket.Connect serverB, portB
  • mySocket.state = 6 sckConnecting
  • событие ошибки сокета вызывается с ошибкой 10060 (WSAETIMEDOUT)
  • mySocket.state = 9 sckError

В этот момент, если я запускаю серверное приложение A, выполняю RAShangup и RASdial и пытаюсь подключиться к серверу A, все работает нормально.

Это как если бы последовательность

socket.connect ip, port
socket.close
socket.connect newIP, newPort

не работает должным образом, если не вставлены RAShangup и RASdial. Вместо этого происходит сбой с WSAETIMEDOUT.

Нужно ли что-нибудь делать между вызовом на закрытие и соединением?

Примечание. Я пытался убедиться, что закрывающий вызов действительно закрыт, но это не помогает:

Private Sub closeSocket(ByRef w As Winsock)
  w.Close
  Do While (w.State <> sckClosed)
    DoEvents
  Loop
End Sub

Ответы [ 2 ]

2 голосов
/ 15 июня 2011

После повторного изучения проекта выясняется, что предыдущий разработчик установил для свойства LocalPort элемента управления winsock ненулевое значение.Это предотвращало повторное использование элемента управления winsock.

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

Извлеченный урок: при работе с VB6 мне нужно посмотреть на настройки свойств, а также на исходный код.

0 голосов
/ 16 июля 2018

Я заметил некоторое странное поведение при закрытии порта. Я не мог повторно открыть порт с последовательностью. Исправление: добавление DoEvents после команды закрытия.

...