【问题标题】:VB6 Asynchronous Tcp Client truncates incoming messagesVB6 异步 Tcp 客户端截断传入的消息
【发布时间】:2011-12-22 21:11:56
【问题描述】:

我有一个向注册的 VB6 Tcp 客户端发送消息的 C# 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。所以很明显,传入消息的截断是一个严重的问题。

以前有人观察过吗?

【问题讨论】:

    标签: networking vb6 tcp


    【解决方案1】:

    正如我在这里所说的VB6 WinSock TCP client and .NET TCP server

    这是一个常见的误解,即您正在接收消息。你 正在接收字节流。 sBuff 可能包含 1 个字节,它可能 包含 50% 的内容构成您的信息,通常(如果它们很小 够了)它可以包含 100% 的信息,有时它可以 包含超过 100%(意味着它包含下一条消息的某些部分)。 如果没有看到 ProcessMessage 中的代码,我无法确定您是否有 问题,但您应该确保该方法可以处理所有这些 场景

    仅仅因为您在 DataArrival 上只看到 2920 的数据长度并不意味着数据被截断。这只是意味着那是当时可用的一切。将该数据读入缓冲区,然后当您发送的数据的下一部分可用时,该事件将再次触发。继续读取可用数据并附加到缓冲区,直到获得完整消息。

    【讨论】:

    • this article 中提供了如何执行此类操作的示例。它是使用 SocketWrench 控件编写的,但概念是相同的。
    • 是的,那个古老的“数据包谬误”又在起作用了。一遍又一遍地解释同样的事情肯定会变老。
    【解决方案2】:

    使用 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
    

    注意: 该代码预期会导致单个流而不是多个套接字响应

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-06
      • 2015-11-05
      • 2019-09-09
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 1970-01-01
      相关资源
      最近更新 更多