Не получайте никаких данных из сокета, когда данные должны быть там, и никаких исключений не возникает, соединение открыто. Использование DataAvailable для ожидания данных - PullRequest
2 голосов
/ 24 марта 2011

У меня проблема с чтением данных с RFID-ридера.Я соединяюсь с читателем по tcp и жду, пока DataAvailable станет истиной, затем читаю данные, пока не получу символ конца данных.Тогда я просто возвращаюсь и жду нового DataAvailable.Это делается в собственном потоке для функции.

Кажется, есть какой-то тайм-аут, если я не получаю никаких данных в течение нескольких минут, то он просто сидит в цикле do /ожидание данных доступно.Я держу карту в считывателе RFID, она издает звуковой сигнал, но нет доступных данных.Я не получаю никаких исключений, и информация говорит о том, что клиентская розетка все еще подключена.Есть ли что-нибудь еще, что я могу проверить?

Если я положу карту в считывающее устройство с минутным интервалом, кажется, что этого никогда не произойдет.Так что 2-3 минуты простоя: кажется, что это делает ing.

Вот мой код для чтения данных из сокета, я забрал какой-то неактуальный код:

Sub test(ByVal ip As String, ByVal port As Integer)
    ' this sub is meant to run forever
    Try
        Dim clientSocket As New System.Net.Sockets.TcpClient()
        clientSocket.Connect(ip, port)
        Using serverStream As NetworkStream = clientSocket.GetStream()
            Do 'loop forever or until error occur

                'Every new dataentry starts here
                Dim inStream(0) As Byte
                Dim returndata As String = ""

                Do 'loop forever 
                    Do Until serverStream.DataAvailable 'loop until data exists to read
                        If clientSocket.Connected = False Then

                            'this will never happen.
                            'but if there are more than 5 minutes between data then
                            'it never got data again as if no data was sent.

                            Exit Sub
                        End If
                        Application.DoEvents()
                    Loop

                    'there is data to read, read first byte and 
                    serverStream.Read(inStream, 0, 1)
                    If inStream(0) = 13 Then

                        'got end of data
                        'exit loop if reading chr 13.
                        returndata &= System.Text.Encoding.ASCII.GetString(inStream)
                        Exit Do

                    End If
                Loop

                GotData(returndata)

            Loop
        End Using
    Catch ex As Exception
        ' handle error
    Finally
        'close connection if open
    End Try
End Sub

1 Ответ

2 голосов
/ 24 марта 2011

Я обнаружил, что socket.Connected сообщает только о состоянии, когда была выполнена последняя команда для соединения .Таким образом, в цикле Do Before serverStream.DataAvailable я использовал этот трюк, чтобы проверить, было ли закрыто соединение:

Dim test As Boolean = clientSocket.Client.Poll(10, System.Net.Sockets.SelectMode.SelectRead)
If test = True And serverStream.DataAvailable = False Then
   'restart connection
End If

Так что теперь, наконец, получил контроль над происходящим и знаю, чтоиз-за клиентского соединения закрыто, что я не получил никаких данных.

Итак, я подумал, теперь, когда я знаю, что соединение закрыто, как мне это предотвратить?Это было проще, просто отправляйте данные на tcpip-сервер каждые 10 секунд, и он останется открытым.

Результат, который работает для меня (это не рабочий код, а просто пример решения):

    Dim s As Date = Now
    Do Until serverStream.DataAvailable
        Dim r As Boolean = clientSocket.Client.Poll(10, System.Net.Sockets.SelectMode.SelectRead)
        If DateDiff(DateInterval.Second, s, Now) > 10 Then
           Dim dta(0) As Byte
           dta(0) = 0
           clientSocket.Client.Send(dta)
           s = Now
        End If
        If r = True And serverStream.DataAvailable = False Then
             'restart sub
             Exit Sub
        End If
   loop

Так что теперь он даже не закрывается и должен перезапускаться каждые x минут.

Мои проблемы решены, и я счастливый кодер.;)

...