winsock发送数据前先发送一个4字节长度的数据大小给对方 这样就知道将要收到的数据大小来
你这里可以这样
dim v as variant
v=RsToBin(rs)
SockServer(Index).SendData ubound(v) '发送数据大小给客户端客户端检查如果数据大小未指定,且收到的数据大小为4,则设定数据大小,并准备接收数据
例如:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
    Static DateLength As Long, DateBuf() As Byte
    Dim n As Long, b() As Byte
    If DateLength = 0 And bytesTotal = 4 Then                                   '设置将要接收到数据大小
        ReDim DateBuf(0)                                                        '清空释放数据缓存
        Winsock1.GetData DateLength
    ElseIf DateLength > 0 Then
        n = UBound(DateBuf)
        ReDim Preserve DateBuf(n + bytesTotal - 1)
        Winsock1.GetData b
        If n > 0 Then n = n + 1
        CopyMemory DateBuf(n), b(0), bytesTotal                                 '数据复制到缓冲区中
        
        If UBound(DateBuf) + 1 = DateLength Then                                '这里判断数据是否接收完毕
            DateLength = 0                                                      '静态数据变量清零
            '然后这里可以调用BinToRs(DateBuf)还原rs,最后 ReDim DateBuf(0) 清空一下静态数组
        End If
    End If
    
End Sub

解决方案 »

  1.   

    嗯,或者后面加个尾部标记就行,也是一样的。Public Function RsToBin(Rs As Recordset) As Variant
        Dim objStream As Stream
        Set objStream = New Stream
        objStream.Open
        objStream.Type = adTypeBinary
        Rs.Save objStream, adPersistADTG
        objStream.Position = 0
        RsToBin = objStream.Read()
        Set objStream = Nothing
    End Function
    这个地方再 objStream.WRITE几个特殊符号上去就行了,或者你发2次就行,第一次发RsToBin的数据,再发一次“DATAEND",然后把收到的数据比较一下,要是发现是这个标记就说明收完了
      

  2.   

    传输时最底层会自动分包,所以发送端的 SendData 次数和接收端的 DataArrival 次数不一定一一对应。
    发送端可以偷懒,不用主动分包。接收端必须进行包的合并处理。
    约定采用先发送一个长度再发数据的方式比较好,不用处理特殊标志(接收缓冲区会出现多个数据包共存的情况,特殊标志只能靠全文搜索而不能直接定位)。
      

  3.   

    二楼的,跟根你的思路,已经做成可以接收多次的数据了,但有一点始不明白,分次接收时,那长度始终对不上。
             Static j As Integer
              j = j + 1
            
            
            Winsock1.GetData bd, vbArray + vbByte
            
            
            '重定义缓冲区大小
            n = UBound(DateBuf)
            If n > 0 Then n = n + 1
            
            ReDim Preserve DateBuf(n + bytesTotal - 1)
            CopyMemory DateBuf(n), bd(0), bytesTotal                                '数据复制到缓冲区中
            
            Debug.Print "第" & j & "次接收 实收:" & bytesTotal & "  有效数据:" & UBound(bd) & "  总接收:" & UBound(DateBuf) & " " & Round(UBound(DateBuf) / DateLength, 2) * 100 & "%"
            
            
            
            If UBound(DateBuf) >= DateLength Then                                   '这里判断数据是否接收完毕
                '收到的如果是数据集则显示出来
                Set DataGrid1.DataSource = BinToRs(DateBuf)
                DateLength = 0                                                      '清零静态数据长度
                ReDim DateBuf(0)                                                    '清空缓冲区
                j = 0
            End If一、服务器计算记录长度为 UBound:62773   LenB:62774  我的是的UBound:62773  同一个记录集,不同结果。
    二、先发送长度62773   到客户端,再发送数据,客户端接收明细为如下,需要接收长度:62773
    第1次接收 实收:3954  有效数据:3953  总接收:3953 6%
    第2次接收 实收:8192  有效数据:8191  总接收:12145 19%
    第3次接收 实收:8192  有效数据:8191  总接收:20337 32%
    第4次接收 实收:8192  有效数据:8191  总接收:28529 45%
    第5次接收 实收:8192  有效数据:8191  总接收:36721 58%
    第6次接收 实收:8192  有效数据:8191  总接收:44913 72%
    第7次接收 实收:8192  有效数据:8191  总接收:53105 85%
    第8次接收 实收:8192  有效数据:8191  总接收:61297 98%
    第9次接收 实收:1477  有效数据:1476  总接收:62774 100%第二次接收时,应是3953 +8191  =12144 而缓冲区数组已经是12145
    第三接收收时,应是3953 +8191 +8191  =20335   而缓冲区数组已经是20337 
    到最后,总接收是62774 与需要的62773,总是大于1不知你们这一块是怎么弄法的?给点高见
      

  4.   

    你是没认真看我的判断吧,我给你写的是If UBound(DateBuf) + 1 = DateLength Then
      

  5.   

    如果发送到时候是ubound(v)的长度,If UBound(DateBuf)  = DateLength Then这样判断就对了 
      

  6.   

    你每次的“有效数据”值不对啊,
    有效数据=UBound(bd)+1
    因为这代码中,下标是0开始的。
    这个结果,跟你的“实收”才相符。
    你要是每次都把有效数据量少算1字节,
    多次累计下来,已经差得比较多了,
    最严重的是,你这样造成了数据没办法还原,
    记录集不能“重建”(或重建后记录集是错的)。
      

  7.   

    接收回来的总是比发送的大现在服务器端,ubound(v)=3823小于8K一次接收完成
    客户端 bytesTotal=3825  UBound(bd)=3824多出来的一位是结束符吗?
      

  8.   

    服务器端很简单,
                    Debug.Print "发送记录集:" & UBound(RsToBin(rs)) & "    " & LenB(RsToBin(rs))
                    SockServer(Index).SendData RsToBin(rs)
      

  9.   

    我也遇到了这个问题,是发送9k数据时出现最后3k传不全,最先想到的是分批次传,然后客户端解析按照发送的方式对应解析,后来干脆换数据库sql,就彻底解决了
      

  10.   

    myjian 有例子,参考一下。
      

  11.   

    本来不想回复的 这完全是你自己的基础问题
    UBound(bd)=3824 实际数据长度是3825,知道吗
    上限是从0开始的 自己用手指从0数到9看看是多少
      

  12.   

    UBound(bd)=3824 实际数据长度是3825这个我知道,问题是客户端的长度不等于服务器的长度就是  UBound(bd)<>UBound(v)
    两边都是常规操作。谢谢以上各位了,现在能用就行了,有时间再研究一下