查看: 413  |  回复: 0
  VB6 Winsock控件获得请求每次都是8192字节以内,无法只取1个字节而清空缓存区。
楼主
发表于 2024年4月6日 16:58

新建From1(窗体),新建Command1(按钮CommandButton),WinsockS(服务端) 和 WinsockC(客户端)(Winsock)代码:

Private Sub Form_Unload(Cancel As Integer)
    If WinsockS.State <> 0 Then WinsockS.Close
End Sub

Private Sub Form_Load()
    WinsockS.Protocol = sckUDPProtocol
    WinsockS.LocalPort = 888
    WinsockS.Bind
End Sub

Private Sub WinsockS_DataArrival(ByVal bytesTotal As Long)
    'Dim bByteDiscard(10) As Byte '固定数组取不到任何数据,都是0
    Dim bByteDiscard() As Byte    '动态数组可以取数据
    ReDim bByteDiscard(bytesTotal - 1) '正确的做法
    'ReDim bByteDiscard(0) '填任何数都是取bytesTotal - 1个字节
    On Error Resume Next '虽然报错,但是仍然是截取了,并且清空了缓存
    WinsockS.GetData bByteDiscard, , 0 '取0个字节,便于丢包
    Debug.Print UBound(bByteDiscard) '结果-1 本地窗口可以看到是(0 to -1)
    
    '被上面取了数据,已经无数据可取了,就是空,显示0
    Dim bQuery() As Byte
    ReDim bQuery(bytesTotal - 1)
    WinsockS.GetData bQuery
mark1: '这里打断点用本地窗口看变量和值
End Sub

Private Sub Command1_Click()
    Dim arrB() As Byte
    ReDim arrB(2)
    arrB(0) = 10
    arrB(1) = 11
    arrB(2) = 12
    
    If WinsockC.State <> 0 Then WinsockC.Close
    WinsockC.Protocol = sckUDPProtocol
    WinsockC.RemoteHost = "127.0.0.1"
    WinsockC.RemotePort = 888
    WinsockC.LocalPort = 0
    WinsockC.Bind

    WinsockC.SendData arrB()
End Sub

在WinsockS_DataArrival的mark1后打断点,运行后通过本地窗口可以看到我的注释。

看来Winsock控件没有看到bytesTotal>100就快速丢包,而不用每次做多获得8192字节,无法只取1个字节而清空缓存区。通过On Error Resume Next和WinsockS.GetData bByteDiscard, , 0配合可以取0个字节的内容。

我还发现,如果在WinsockS_DataArrival不读缓冲区的时候感觉正常,加个MsgBox "ok",就算是1个请求也会循环提示,所以必须读!

您需要登录后才可以回帖 登录 | 立即注册
【本版规则】请勿发表违反国家法律的内容,否则会被冻结账号和删贴。
用户名: 立即注册
密码:
2020-2024 MaNongKu.com