簡體   English   中英

VB6異步Tcp客戶端截斷傳入的消息

[英]VB6 Asynchronous Tcp Client truncates incoming messages

我有一個C#Tcp服務器,它向已注冊的VB6 Tcp客戶端發送消息。 消息的接收是以異步方式使用WinSock完成的。 所以“完成”消息的VB6部分看起來像:

Private Sub wskConnect_DataArrival(ByVal bytesTotal As Long)
   Dim sBuff As String
   wskConnect.GetData sBuff, vbString       '-- Retrieve sent value
   ProcessMessage sBuff                     '-- Process the value
End Sub

問題是C#Tcp服務器正在發送一個長度為6874的字符串,但是當我們檢查DataArrival事件觸發時收到的消息大小時,它只測量2920.所以很明顯這個傳入消息的截斷是嚴重的問題。

有沒有人觀察過這個?

正如我在這里所說的VB6 WinSock TCP客戶端和.NET TCP服務器

這是一種常見的誤解,即您正在接收消息。 您正在接收字節流。 sBuff可能包含1個字節,它可能包含構成您的消息的50%,通常(如果它們足夠小)它可以保留100%的消息,有時它可以包含超過100%(意味着它有一些部分)下一條消息)。 沒有看到ProcessMessage中的代碼我不能確定你有問題,但你應該確保該方法可以處理所有這些場景

僅僅因為您在DataArrival上只看到數據長度為2920並不意味着數據被截斷。 它只是意味着那一刻就可以獲得。 將該數據讀入緩沖區,然后當您發送的數據的下一部分可用時,該事件將再次觸發。 繼續讀取可用數據並附加到緩沖區,直到您收到整條消息。

使用mscomm控件存在同樣的問題。 使用異步事件總是很有用。

首先,這是我個人處理它的方式可能存在其他更好的方式。 所以這是一個選擇。

我遇到過這個問題不止一次,而且我常常忘記如何處理這個問題。 所以這也是我個人的參考

首先是這個想法

create time of expiration when it became to be reached 
the information should be complete

我們需要了解事件是如何發生的

圖形視圖是死時間,死時間只是一個時間段

死時間視圖

現在在vb6中,當異步事件發生時,還需要在不同的瞬間發生兩個動作,但在同一時刻進行測試

Action #1 that action update the current time 

經常性的時間

Actions #2 that is limited to update the time current time for async event

更新異步事件的時間

Both event are combined on one infinity loop method
the purpose is check current time against the current time of async event

驗證兩個計數器時間

此外,我們需要一些實用程序來跟蹤我使用win api GetTickCount的時間

在mscomm中我們還需要添加標志和字符串,以便知道是否有人收到了它,因為在端口的接口調用中沒有等待太多

此外,該代碼可以將事件拋出以供重用和隔離

現在看到vb6類的骨架

class Module SocketReceptorVb6

   Private Declare Function GetTickCount Lib "kernel32" () As Long   ' API tick

   withevents _tcpControll as Winsock

   private m_currentState As Eventstate  'is a enumerate Waiting, Receiving
   private m_currentTimeAsynEvent As Long  ' current time for async event
   private m_buffer As String
   private m_timeOut as Long

   Public Event StreamReceived(ByVal stream As String) 'Event completed

   Property TimeOut

   private sub Class_Initialize() 
     m_currentState = Waiting
   end sub

   sub tcpControl_DataArrival(bytesTotal)          

   sub Receiving

   sub InitFlags       

End Class

那么現在更仔細地看看3種方法

InitFlags Method

那個干凈的變量和准備環境,看到內容

m_currentState = Waiting //state of the process
m_buffer = vbNullString  //reset the buffer used for the information

tcpControl_DataArrival Method

該方法有下一個職責

   -update buffer 
   -initialize infinity loop 
   -update m_currentTimeAsynEvent

方法的內容

Dim sBuff As String
wskConnect.GetData sBuff, vbString

m_buffer = m_buffer & sBuff

' update time for Asyn Event
m_currentTimeAsynEvent = GetTickCount()

if m_currentState = Waiting then
  m_currentState = Receiving
  InfinityLoop()
end if

InfinityLoop Method
verify that the expiration time has been reached

Content method

Dim current_time As Long        ' the time point o current time

 Do
     current_time = GetTickCount()
     ' timeout reach, exit of loop
     If current_time > m_currentTimeAsynEvent + m_timeOut Then
         Exit Do
     End If
     DoEvents
 Loop

 RaiseEvent StreamReceived(m_buffer)
 InitFlags 'Reset flags and variables

注意: 該代碼預期帶有單個流而不是多個套接字響應

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM