VB6 异步 Tcp 客户端截断传入消息

发布于 2024-12-22 16:33:57 字数 478 浏览 2 评论 0原文

我有一个 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。很明显,传入消息的截断是一个严重的问题。

以前有人观察过这一点吗?

I have a C# Tcp server that sends messages to registered VB6 Tcp clients. The receiving of the message is done using WinSock in an asynchronous fashion. So the VB6 part where the "completed" message comes in looks like:

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

The problem that is that the C# Tcp server is sending a string of length 6874, but when we check the size of the message as received when the DataArrival event fires, it measure only 2920. So clearly this truncation of the incoming message is a severe problem.

Has anyone observed this before?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尐偏执 2024-12-29 16:33:57

正如我在这里所说的VB6 WinSock TCP客户端和.NET TCP服务器

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

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

As I said here VB6 WinSock TCP client and .NET TCP server:

That is a common misconception, that you are receiving messages. You
are receiving a stream of bytes. sBuff may contain 1 byte, it may
contain 50% of what makes up your message, often (if they are small
enough) it can conatin 100% of your message, and sometimes it can
contain more than 100% (meaning it has some part of the next message).
Without seeing the code in ProcessMessage I cannot be sure you have a
problem, but you should make sure that method can handle all of these
scenarios

Just because you only see a data length of 2920 on DataArrival doesn't mean the data was truncated. It just means that that was all that was available at that moment. Read that data into a buffer, and then when the next part of the data you sent is available the event will fire again. Continue to read the available data and append to your buffer until you have the whole message.

无边思念无边月 2024-12-29 16:33:57

使用mscomm控件也存在同样的问题。
处理异步事件总是很困难。

首先这是我个人的处理方式
可能以其他更好的方式存在。所以这又多了一种选择。

我不止一次遇到这个问题,而且经常忘记如何解决
处理这个问题。所以这也是我个人的参考

首先

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

,我们需要了解事件是如何发生的

图形视图是死区时间,死区时间只是一个时间段

Dead Time view

现在,在 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

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

With mscomm control exists the same problem.
Work with async events always its harded.

First that is my personal way of deal with it
probably exist other way better. so it is one option more.

I've run into this problem more than one times and it often i forget how
deal with that. so that also be my personal reference

First the idea

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

well we need understand how the events happen

Graphic view that be the dead time, the dead time just is a time period

Dead Time view

Now in vb6 when async events happen also need to happen two actions in different instant but are tested in the same moment

Action #1 that action update the current time 

Recurrent time

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

update 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

verification for both counter times

Also we will need some utility for keep track of time i used the win api GetTickCount

In mscomm also we will need add flag and string for know if some was received it for not wait so much in call to interface in the port

Also that code can throw event it for reuse and isolate

now see the skeleton of vb6 class

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

well now look at the 3 methods more closely

InitFlags Method

That clean variables and prepare the ambient, see the content

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

tcpControl_DataArrival Method

That method have the next responsibilities

   -update buffer 
   -initialize infinity loop 
   -update m_currentTimeAsynEvent

content of the method

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

Note:
that code expected lead with a single stream not multiple socket responses

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文