2011-03-24 1 views
2

RFID 리더에서 데이터를 읽는 데 문제가 있습니다. 나는 tcp에 의해 독자에게 연결하고 DataAvailable이 참이 될 때까지 기다린 다음 데이터 문자가 끝날 때까지 데이터를 읽는다. 그런 다음 다시 돌아가 새로운 DataAvailable을 기다리고 있습니다. 이것은 함수에 대한 자체 스레드에서 수행됩니다.데이터가있을 때 소켓에서 데이터를 가져 오지 않고 예외가 발생하지 않고 연결이 열려 있습니다. DataAvailable을 사용하여 데이터 대기

몇 가지 종류의 시간 초과가있는 것 같습니다. 몇 분 안에 데이터가 없으면 DataAvailable을 기다리는 do/loop에 그냥 앉아 있습니다. 나는 RFID 판독기에 카드를 붙잡고 있지만 신호음이 들리지만 사용할 수있는 데이터가 없습니다. 예외는 없지만 clientsocket은 여전히 ​​연결되어 있다고합니다. 더 확인할 수있는 것이 있습니까?

분 간격으로 카드를 리더기에 놓으면 결코 발생하지 않는 것처럼 보입니다. 따라서 2-3 분 동안 유휴 상태가 유지되는 것 같습니다.

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 
+0

나는 이것이 당신의 문제를 해결할 것이라고 생각하지 않지만 닫는 바깥 쪽 루프 앞에 거기에'Thread.Sleep (int)'를 추가 할 것을 권한다. 아마도 '100'또는 '250'으로 설정하십시오. 그렇지 않으면 CPU주기를 낭비하는 매우 단호한 원으로 회전하고 있습니다. 그 외부 루프는 실제로 밀리 초 당 수백 번 실행될 수 있습니다. –

+0

@Chris, 덕분에, 내 application.doevents가 OS에 CPU주기를 되돌려주는 것처럼 보입니다. 대부분의 경우 프로그램이 "데이터 대기"내부에서 실행됩니다. -loop 그래서 거기에 넣습니다. 하지만 아마도 thread.sleep으로 대체해야합니다. – Stefan

답변

2

내가 socket.Connected 는 마지막 명령에 runned 때의 상태를보고 있음을 발견 : 여기

가 소켓에서 데이터를 읽어 내 코드입니다, 나는 몇 가지 관련이없는 코드를 날라왔다 연결. 그래서 연결이 대신 닫힌 경우 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 

가 이제 마지막으로 무슨 일이 일어나고 있는지에 대한 제어를 가지고와 그 때문에 클라이언트 연결을 알고 나는 어떤 데이터도 갖고 있지 않다.

그럼 연결이 닫혔다는 것을 알았으니 어떻게 막을 수 있습니까? 그것은 더 쉬웠고 단지 10 초마다 tcpip-server에 데이터를 보내면 열리게됩니다.

나를 위해 작동 결과는 (이 생산 코드, 솔루션의 단지 예되지 않음) :

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 분을 다시 시작해야합니다.

내 문제가 해결되었으며 행복한 코더입니다. ;)

+1

좋습니다. 쿼리가 수행 될 때 이전 상태가 아닌 현재 상태를 예상하므로이 폴링이 내장되어 있어야합니다. 이는 혼란의 원인입니다. – kobi7

관련 문제