2016-05-31 2 views
2

Я сделал программное обеспечение пару лет назад, используя VB6, который работает как TCP-сервер, получает несколько подключений от клиентов.VB6 Winsock несколько TCP-соединений> проблемы с DoEvents

Основная идея программного обеспечения является прослушивание определенного порта, принимать соединения от различных клиентов и передавать каждое соединение в отдельный Winsock, который анализирует данные, смотрит в БД, отвечает с соответствующим сообщением, а затем закрывает соединение.

Вот код:

Инициализация сокетов при запуске приложения:

For i = 1 To MaxCon  
    Load sckAccept(i) 
Next i 
sckListen.Listen 

принимает соединения:

Private Sub sckListen_ConnectionRequest(ByVal requestID As Long) 
    Dim aFreeSocket As Integer 
    aFreeSocket = GetFreeSocket 
    If aFreeSocket = 0 Then 
     sckAccept(0).Accept requestID 
     sckAccept(0).SendData "Server is full!" 
     sckAccept(0).Close 
    Else 
     sckAccept(aFreeSocket).Accept requestID   
End Sub 

Получение данных, анализ, и ответ :

Private Sub sckAccept_DataArrival(Index As Integer, ByVal bytesTotal As Long) 
    Dim sData As String 
    sckAccept(Index).GetData sData 
    'Do lots of analyizing and search in DB 
    ' 
    ' 
    sckAccept(Index).SendData "Message" 
    ' 
    ' 
    DoEvents 
    sckAccept(Index).Close 
End Sub 

Все работало отлично, но теперь количество подключений увеличилось (пара десятков в секунду), так что программное обеспечение начало получать Out of stack space исключение (из-за DoEvents).

Я знаю, что во многих случаях DoEvents является злым, но если я его удалю, пользовательский интерфейс приложения не ответит (из-за чрезмерной нагрузки на поток), и некоторые данные могут не быть доставлены.

Итак, мой вопрос: есть ли у кого-нибудь идеи, как обойти эту проблему с использованием/без использования DoEvents?


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

+0

Я, честно говоря, не понимаю, почему должно произойти в последней строке обработчика данных, я бы поставил его внутри тяжелой петли. Технически, события имеют простой «выход», поэтому ошибка со стеком может иметь другой источник, такой как размер sdata, я бы разместил его в массиве снаружи и получал доступ к нему с помощью индекса соединения, я прекрасно понимаю, что это грязно, но должен помочь спасти кучу. – Gar

+0

1- Я помещаю 'DoEvents' внутри обработчика DataArrival', потому что он вызывает« Winsock.SendData »и« если я его удалю, пользовательский интерфейс приложения не будет отвечать (из-за чрезмерной нагрузки на поток), и некоторые данные могут не доставляться ". 2- Что вы подразумеваете под «большой нагрузкой»? 3- Когда возникает ошибка «Out of stack space», стек заполнен событиями 'sckAccept_DataArrival'. Я предполагаю, что это потому, что «DoEvents» позволяет снова запускать событие (которое содержит еще один «DoEvents» и т. Д.). 4- Размер 'sData' довольно мал (40-100 байт) –

+0

Я полностью понимаю, почему вы использовали события, я просто не вижу его до конца sub, я использую« doevents »внутри петель, так что цикл не блокирует приложение. И даже если sdata является небольшим, вы можете заработать лишь немного места, оставив его вне и ничего не потерять. Я также понимаю, что причиной вашей проблемы является укладка нерешенных запросов tcp (поскольку их обработчик запрашивает для них базу данных). – Gar

ответ

1

Ну, мне удалось выяснить проблему и решить ее.

Короткий ответ

НЕ используйте DoEvents .. Некоторые данные не будут доставлены? Ну, закройте соединение ТОЛЬКО в событии SendComplete.


Длинный ответ

Первое первый:

Почему я DoEvents в первую очередь? потому что некоторые из отправили сообщений не доставлялись. Многие статьи/вопросы в Интернете предлагают использовать DoEvents после Socket.SendData, чтобы гарантировать прибытие данных в приемник.

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

Socket.SendData "Message" 
' 
' 
Socket.Close 

Итак, я просто переместил линию, которая закрывает подключение к SendComplete событию, снял DoEvents приговор -since я не делаю нужно anymore-, и проблема исчезла :)

Private Sub sckAccept_SendComplete(Index As Integer) 
    sckAccept_Close (Index) 
End Sub 

Я надеюсь, что это может помочь кому-то, кто имеет такую ​​же проблему.

Смежные вопросы