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
问题是这么写取不到,客户端发送过来的数据,我知道我在服务器的接收代码写错了哪里,才会接收不到正确的数据
各位帮忙看一下,谢谢
客户端大概代码: 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
问题是这么写取不到,客户端发送过来的数据,我知道我在服务器的接收代码写错了哪里,才会接收不到正确的数据
各位帮忙看一下,谢谢
但接收后,我怎么把数据复制给结构体呢
比如:Dim FileByte As Byte
total = Winsock1.BytesReceived '取得最终数据字节这样不会少
Winsock1.GetData FileByte ', vbArray + vbByte '接收类型为:字节数组那么下面这句怎么写?
CopyMemory sendData, FileByte,total '这样写报错
sockData 结构只有两个成员 SAFEARRAY*、BSTR,它们都是指针。
LenB(sendData) 始终 = 8。将两个指针值传递到另外一台计算机有什么意义?
你声明的 sockData 类型的变量始终只点8个字节。
sendData.bteFileData() 中的“具体内容”实际并没有发送到服务器端。
字符串,而我在服务器端需要正确的区分,二这种数据,并储存起来!
例如:客户端,发送包格式大概如下:
sock.sendData "这里是字符串" & "/" & 这里是字节数组
我想了很久,可能是我能力有限,对于上面的包,我在服务器端怎么拆也拆不正确的数据出来.
所以我才想,在客户端构建一个结构体,将上面二种数据分别存入结构体中,然后把这个结构体的内存地址,直接复制给数组
再把数组发送给服务器端,最后在服务器端再将结构体还原出来.
参考一下我的这段代码:
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
应该是: For i = 0 To bLen - 1
首先可以肯定要发送的字节数组一共为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是需要区分开来字符串
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
不能讨论‘效率’的问题。效率要根据实现的实现过程,才能比较孰优孰劣。不管怎么说,sockData类型的变量仅包含“两个指针”,而你需要的内容并没有在这个结构体中。
必须把这些“具体内容”Copy 到一个字节数组内,才能进行传送。
============================================
你的代码有问题: ~~~~~
..........
Dim tempa As String * 4
.........
tempa = SendLen + 7
Sendbaye = tempa ' 把长度负值给包头
这里没有语法错误?
Sendbaye 与 tempa 类型恐怕不会“兼容”吧!能直接赋值?前面ReDim Sendbaye(0)纯属多余的。===================================不走不行了,偶要上班去.............
等会儿就有高人出现了,你别着急~~~~~~
^_^
ReDim Sendbaye(0)
ReDim FileByte(SendLen - 1)
tempa = SendLen + 7
Sendbaye = tempa ' 把长度负值给包头;------------------------------
绝对不会错哈,VB的招牌变量类型Variant
其实Variant这个数据类型还是蛮好用的,特别是在API里面当确实不知道是什么类型时
定义一个Variant的变量,然后来个typename()真实的数据类型就出来了:)
不过Variant这种类型的变量,会比定义过类型的变量,占用的内存更多,不过也只是一时的,当有数据接收时,
VB就自己给你定义了!!总结一下哈:自己还得多多努力,,
你这样可能会造成一些意想不到的麻烦。
这个东东貌似“很灵活”,但还是少用为妙。
我的VB代码中,从来没使用过 Variant 类型的变量!
至于数据结构,真的要好好回味一下,学的都忘得差不多了(因为不大用),现在要重组
数据序列,让重组过的数据序列,只能在指定的PC上运行,离开这个PC,将打不开这种
特殊结构的数据文件