none
Ошибка в приложении клиент-сервер RRS feed

  • Вопрос

  • Добрый вечер. Очень интересная ситуация, может подскажите кто чем. Есть приложение клиент-серверное. Передает по TCP информацию. Если что, ниже кусочки кода приведу.

    Вот клиент подключается к серверу

    'Начало чтения
        Public Function Connect(ByVal Server As String, ByVal Port As Integer) As Boolean
            Try
                myClient = New TcpClient(Server, Port)
                Writer = New BinaryWriter(myClient.GetStream)
    
                'Запускаем поток обработки
                ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf DoRead))
    
                Return True
            Catch ex As Exception
                Return False
            End Try
        End Function
    
        'Получения блока байт информации
        Public Sub DoRead(ByVal obj As Object)
            Try
                Dim Stream As NetworkStream = myClient.GetStream
                Dim Reader As New BinaryReader(Stream)
                Dim typeByte As Byte
                Do
                    Dim typeMsg = Reader.ReadByte()
                    'Далее смотрим заголовок
                    Select Case typeMsg
                        Case READ_SYSTEM 'Сообщение
                            Dim tmpName = Reader.ReadString
                            Dim tmpMessage = Reader.ReadString
                            Try
                                RaiseEvent MessageReceived(Me, tmpName, getDataFromMessages(tmpMessage))
                            Catch ex As Exception
                                Dispose("Ошибка 49: Обработка блока данных #" & READ_SYSTEM & " выдало исключение. " & ex.Message)
                            End Try                 
                    End Select
                Loop While Stream.CanRead
            Catch ex As Exception
                Dispose("Сервер принудительно разорвал существующее подключение. Причина - " & ex.Message)
            End Try
        End Sub


    Вот так  выглядит часть кода сервера

      
     'Старт сервера...
        Public Sub ServerStart(ByVal Port As Object)
            Listener = New TcpListener(IPAddress.Any, CInt(Port))
            Listener.Start()
            While StatusServer
                Try
                    'Ждем пока кто нибудь не подключится...
                    Dim Client = New ClientServer(Listener.AcceptTcpClient)
                    ThreadPool.QueueUserWorkItem(New WaitCallback(Sub()    
                                                                      Client.DoRead()
                                                                  End Sub))
                    OnlineList.TryAdd(Client.IP, Client)
                Catch ex As Exception
                End Try
            End While
        End Sub
    
    'КЛАСС КЛИЕНТА
    
      'Начало чтения
        Public Sub New(ByVal Client As TcpClient)
            IP = CType(Client.Client.RemoteEndPoint, Net.IPEndPoint).Address.ToString
            SetLogMessage(Me, "ЗАПУСК клиента... " & IP)
            myClient = Client
            Writer = New BinaryWriter(myClient.GetStream)
    
    End Sub
        'Получения блока байт информации
        Public Sub DoRead()
            Try
                Dim Stream As NetworkStream = myClient.GetStream
                Dim Reader As New BinaryReader(Stream)
                Dim typeByte As Byte
                Do
                    Dim typeMsg = Reader.ReadByte() 'Тип сообщения
                    'Далее смотрим заголовок
                    Select Case typeMsg
                        Case READ_SYSTEM 'Сообщение
                            Dim tmpName = Reader.ReadString
                            Dim tmpMessage = Reader.ReadString                      
                            OnMessageReceived(tmpName, getDataFromMessages(tmpMessage))
                    End Select
                Loop           
            Catch ex As Exception
                If StatusJoin Then
                        SetLogMessage(Me, "Отключение клиента [" & IP & "] / обрыв связи")
                End If
            End Try
        End Sub

    Отправка на сервер данных и клиенту таким образом

        Public Sub SendData(NameMessage As String, data As String)
            Try
                SyncLock SendDataLock               
                    Writer.Write(READ_SYSTEM)
                    Writer.Write(NameMessage)
                    'Теперь само сообщение
                    Writer.Write(data)
                    Writer.Flush()
                End SyncLock
            Catch ex As Exception
                SetLogMessage(Me, "Сообщение клиенту не отправлено. Причина - " & ex.Message)
            End Try
        End Sub

    Теперь сам вопрос. Все работает отлично, но не у всех. Есть компьютеры, на которых теряется соединение с сервером. На сервере в логе просто отключение клиента. А у клиента выводит следующее:

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

    И приходится заново подключатся к серверу. Стоит клиенту принять несколько запросов и отправить парочку - отключается. Может и сразу отключится, пытаясь отправить запрос на сервер. Что это такое может быть? На форумах читал про NAT на маршрутизаторе. Что сервер не может нормально отправлять запросы, они не доходят. Если это так, как эту проблему решить? Ведь другие программы, браузеры и мессенджеры работают хорошо.

    Порт сервера 12321. Может браузеры и другие программы используют стандартные порты, там ... 80, 443? А этот необходимо прописывать?



    • Изменено Siompc 25 марта 2023 г. 19:18
    25 марта 2023 г. 19:16

Ответы

  • Вы вроде уже создавали подобную тему, и тогда выяснилось, что проблема была на стороне провайдера? Я бы и тут смотрел на любые локальные проблемы: с компьютером, с провайдером, с сетевым оборудованием. То, что другие приложения работают, не показатель, они могут просто меньше нагружать сеть, особенно на отдачу. У меня был недавно такой случай, на удаленном пункте, подключенном через VPN к основному офису, поставили одну программу, которая работает с общими сетевыми дисками на файловом сервере. При попытке записать на сетевой диск большой объем данных роутер наглухо умирал, так что оставалось только физически перезагружать. При этом интернет отлично работал, через браузер скачивались сколь угодно большие файлы. Оказалось, что это глюк в прошивке роутера, который проявлялся таким специфичным образом.

    Еще одной возможной проблемой может быть количество одновременно открытых соединений. Например, параллельно с вашей программой работает какой-нибудь торрент клиент, который создает слишком много соединений, и вы упираетесь в ограничение системы.

    • Помечено в качестве ответа Siompc 9 апреля 2023 г. 22:04
    29 марта 2023 г. 17:16

Все ответы

  • На сервере порты проброшены. Проблема со стороны клиента
    26 марта 2023 г. 9:24
  • Здравствуйте,

    А клиенты, которые отключаются всегда одни и те же? Или на случайном принципе? Просто если набор компютеров, которые теряют соединение всегда один и тот же, то скорее есть закономерность связанная с ними, независимо проблема на клиенте или на сервере.


    Если Вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение" Мнения, высказанные здесь, являются отражение моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.


    27 марта 2023 г. 11:15
    Модератор
  • Именно некоторые компьютеры. Проблема в компьютерах однозначно. Но что может выдавать такую ошибку. На одном из компьютеров я пробовал отключать антивирус, порты в брандмауере прописывать и вообще его отключать. Какие причины могут быть кроме портов и фаерволов? Я заметил, что ошибки чаще начинаются когда идет большой поток информации. Когда передается файл, например. Или большие данные запроса. Если файл небольшой - то еще иногда все проходит хорошо. Если же данных много есть большой шанс, что на каком-то моменте клиент ловит ошибку и отключается. Такое ощущение, что он не успевает обработать все данные от сервера.
    29 марта 2023 г. 9:22
  • Вы вроде уже создавали подобную тему, и тогда выяснилось, что проблема была на стороне провайдера? Я бы и тут смотрел на любые локальные проблемы: с компьютером, с провайдером, с сетевым оборудованием. То, что другие приложения работают, не показатель, они могут просто меньше нагружать сеть, особенно на отдачу. У меня был недавно такой случай, на удаленном пункте, подключенном через VPN к основному офису, поставили одну программу, которая работает с общими сетевыми дисками на файловом сервере. При попытке записать на сетевой диск большой объем данных роутер наглухо умирал, так что оставалось только физически перезагружать. При этом интернет отлично работал, через браузер скачивались сколь угодно большие файлы. Оказалось, что это глюк в прошивке роутера, который проявлялся таким специфичным образом.

    Еще одной возможной проблемой может быть количество одновременно открытых соединений. Например, параллельно с вашей программой работает какой-нибудь торрент клиент, который создает слишком много соединений, и вы упираетесь в ограничение системы.

    • Помечено в качестве ответа Siompc 9 апреля 2023 г. 22:04
    29 марта 2023 г. 17:16