Q:
客户端大概代码:  Private Type sockData
    bteFileData() As Byte
    strReqirt     As String
  End TypeDim sendData As sockData
Dim byte_s()  As Byte                  
sendData.bteFileData = Sendbaye     'sendbaye是个字节数组,这里面的数据我不写来,模拟一下
sendData.strReqirt = "CC"
            
k = LenB(sendData)             
ReDim byte_s(k - 1)            
CopyMemory byte_s(0), sendData, k
Winsock.sendData byte_s(0)服务器端代码:  Private Type sockData
    bteFileData() As Byte
    strReqirt     As String
  End Type  Dim FileByte(0)     As Byte
  Dim strFile   As String
  Dim sendData As sockData
  Dim total As Long
  
  total = Winsock1.BytesReceived   '取得最终数据字节这样不会少
  Winsock1.GetData FileByte(0) ', vbArray + vbByte           '接收类型为:字节数组    CopyMemory sendData, FileByte(0), total
    Debug.Print sendData.bteFileData
    Debug.Print sendData.strReqirt
问题是这么写取不到,客户端发送过来的数据,我知道我在服务器的接收代码写错了哪里,才会接收不到正确的数据
各位帮忙看一下,谢谢

解决方案 »

  1.   

    Dim FileByte(0)     As Byte你定义了一个“只有一个元素的数组”。^_^
      

  2.   

    楼上的,我试过用filebyte去接收
    但接收后,我怎么把数据复制给结构体呢
    比如:Dim FileByte    As Byte
      total = Winsock1.BytesReceived   '取得最终数据字节这样不会少
      Winsock1.GetData FileByte ', vbArray + vbByte           '接收类型为:字节数组那么下面这句怎么写?
    CopyMemory sendData, FileByte,total   '这样写报错
      

  3.   

    错了,上面是dim FileByte() as byte
      

  4.   

    完全错误!
    sockData 结构只有两个成员 SAFEARRAY*、BSTR,它们都是指针。
    LenB(sendData) 始终 = 8。将两个指针值传递到另外一台计算机有什么意义?
      

  5.   

    你的客户端“模拟代码”本身就有问题:
    你声明的 sockData 类型的变量始终只点8个字节。
    sendData.bteFileData() 中的“具体内容”实际并没有发送到服务器端。
      

  6.   

    我知道错了,所以在问问嘛:)是这样的客户端现在需要发送数据给服务器端,之所以定义为结构体,是因为,要发送的数据中有一部份是字节数组,一部份是
    字符串,而我在服务器端需要正确的区分,二这种数据,并储存起来!
    例如:客户端,发送包格式大概如下:
    sock.sendData "这里是字符串" & "/" & 这里是字节数组
    我想了很久,可能是我能力有限,对于上面的包,我在服务器端怎么拆也拆不正确的数据出来.
    所以我才想,在客户端构建一个结构体,将上面二种数据分别存入结构体中,然后把这个结构体的内存地址,直接复制给数组
    再把数组发送给服务器端,最后在服务器端再将结构体还原出来.
      

  7.   

    总算在 VB 中运用了一回“指针”了,嘿嘿~~~~
    参考一下我的这段代码:
    Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Type sockData
        bteFileData() As Byte
        strReqirt     As String
    End TypeSub Test()
    '客户端
        Dim sendData As sockData
        Dim byte_s() As Byte
        '---------------
        Dim bToSend() As Byte
        Dim i&, m&
        
    '    sendData.bteFileData = Sendbaye     'sendbaye是个字节数组,这里面的数据我不写来,模拟一下
    '    sendData.strReqirt = "CC"
    '    k = LenB(sendData)
    '    ReDim byte_s(k - 1)
    '    CopyMemory byte_s(0), sendData, k
    '    Winsock.sendData byte_s(0)
        sendData.strReqirt = "ABCDE"
        ReDim sendData.bteFileData(79)  '假设有80字节数据要发送
        For i = 0 To 79
            sendData.bteFileData(i) = i + i
        Next
        '计算 sendData ‘具体内容’所占空间
        i = (UBound(sendData.bteFileData) + 1) * 1
        m = LenB(sendData.strReqirt)
        '* 1 是:字节型变量每个元素占1字节
        ReDim bToSend(i + m + 7)    'bToSend(m + 8 - 1) 另外附加8个字节把结构信息保存下来
        '必需放在开头
        CopyMemory bToSend(0), i, 4
        CopyMemory bToSend(4), m, 4
        CopyMemory bToSend(8), sendData.bteFileData(0), i
        CopyMemory bToSend(8 + i), ByVal StrPtr(sendData.strReqirt), m
    '    For i = 0 To UBound(bToSend)
    '        Debug.Print i, bToSend(i)
    '    Next
        Call ReceiveData(bToSend)
        
    End SubSub ReceiveData(bDataBuf() As Byte)
    '用这个过程来模拟 Winsock 接收数据后的处理
        Dim recData As sockData
        Dim bLen&, sLen&, i&
        
        CopyMemory bLen, bDataBuf(0), 4
        CopyMemory sLen, bDataBuf(4), 4
        '下面这两句必须进行后才能 Copy 数据
        ReDim recData.bteFileData(bLen)
        recData.strReqirt = String(sLen \ 2, Chr$(0))
        CopyMemory ByVal VarPtr(recData.bteFileData(0)), bDataBuf(8), bLen
        CopyMemory ByVal StrPtr(recData.strReqirt), bDataBuf(8 + bLen), sLen
        For i = 0 To bLen
            Debug.Print i, recData.bteFileData(i)
        Next
        Debug.Print recData.strReqirt
    End Sub
      

  8.   

    最后输出的时候 For i = 0 To bLen
    应该是: For i = 0 To bLen - 1
      

  9.   

    楼上别急着走哈,,我办法也想出来了,,只是想问一下,我的代码和你的代码哪个执行率高点
    首先可以肯定要发送的字节数组一共为1007个字节
    客户端部份代码:Dim FileByte()     As Byte, i       As Long, j       As Long
                      Dim temp     As String
                      ReDim Sendbaye(0)
                      '
                      Dim strSendbyte As String
                      Dim sendData As sockData
                      Dim k As Long
                      Dim f() As Byte
                      Dim h, hh As Integer
                      
                      Dim tempa     As String * 4
                      ReDim FileByte(SendLen - 1)
                      tempa = SendLen + 7
                      Sendbaye = tempa       '   把长度负值给包头
                      Get #FileNumber, , FileByte         '读取文件
                      ReDim Preserve Sendbaye(SendLen + 7)           '把包头+到文件头
                      For i = 0 To UBound(FileByte)
                              Sendbaye(i + 7) = FileByte(i)
                      Next
                      strSendbyte = "/aaa"
                      f = strSendbyte
                      'ReDim f(Len(strSendbyte))
                      ReDim Preserve Sendbaye(UBound(Sendbaye) + UBound(f))
                      For h = 0 To UBound(f)
                        Sendbaye(4008 + h - 1) = f(h)
                      Next h                  Winsock.sendData Sendbaye服务端部份代码:Dim filebytes()       As Byte
      Dim FileByte()        As Byte
      Dim strFile   As String
      Dim sendData As sockData  Winsock1.GetData filebytes ', vbArray + vbByte           '接收类型为:字节数组
      
      '-----------------------------------------------------------
      Dim ii, i2, countnumber As Integer
      Dim bao As String
      ReDim FileByte(4007)
      For ii = 0 To 4007
          FileByte(ii) = filebytes(ii)
      Next ii
      
      countnumber = UBound(filebytes) - 4006
      For i2 = 1 To countnumber
        If Chr(filebytes(4006 + i2)) <> Chr(0) Then
            bao = bao & Chr(filebytes(4006 + i2))
        End If
      Next i2在服务器端最后FileByte是字节数组,bao是需要区分开来字符串
      

  10.   

    不好意思上面代码的字节数组少写了一位:)
    ReDim Preserve Sendbaye(UBound(Sendbaye) + UBound(f)+1)'----------------------
    countnumber = UBound(filebytes) - 4007
      For i2 = 1 To countnumber
        If Chr(filebytes(4007 + i2)) <> Chr(0) Then
            bao = bao & Chr(filebytes(4007 + i2))
        End If
      Next i2
      

  11.   

    我的代码仅仅是演示怎样Copy、怎样转换。
    不能讨论‘效率’的问题。效率要根据实现的实现过程,才能比较孰优孰劣。不管怎么说,sockData类型的变量仅包含“两个指针”,而你需要的内容并没有在这个结构体中。
    必须把这些“具体内容”Copy 到一个字节数组内,才能进行传送。
    ============================================
    你的代码有问题:  ~~~~~
    ..........
    Dim tempa As String * 4
    .........
    tempa = SendLen + 7
    Sendbaye = tempa       '   把长度负值给包头

    这里没有语法错误?
    Sendbaye 与 tempa 类型恐怕不会“兼容”吧!能直接赋值?前面ReDim Sendbaye(0)纯属多余的。===================================不走不行了,偶要上班去.............
    等会儿就有高人出现了,你别着急~~~~~~
    ^_^
      

  12.   

    Dim tempa     As String * 4  
    ReDim Sendbaye(0)
              
    ReDim FileByte(SendLen - 1)      
    tempa = SendLen + 7             
    Sendbaye = tempa       '   把长度负值给包头;------------------------------
    绝对不会错哈,VB的招牌变量类型Variant
    其实Variant这个数据类型还是蛮好用的,特别是在API里面当确实不知道是什么类型时
    定义一个Variant的变量,然后来个typename()真实的数据类型就出来了:)
    不过Variant这种类型的变量,会比定义过类型的变量,占用的内存更多,不过也只是一时的,当有数据接收时,
    VB就自己给你定义了!!总结一下哈:自己还得多多努力,,
      

  13.   


    你这样可能会造成一些意想不到的麻烦。
    这个东东貌似“很灵活”,但还是少用为妙。
    我的VB代码中,从来没使用过 Variant 类型的变量!
      

  14.   

    我从不用Variant 类型,只是一开始学API的时候,这样用过,后来也就没这样用过:)
    至于数据结构,真的要好好回味一下,学的都忘得差不多了(因为不大用),现在要重组
    数据序列,让重组过的数据序列,只能在指定的PC上运行,离开这个PC,将打不开这种
    特殊结构的数据文件