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
你这里可以这样
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
解决方案 »
- vb服务器
- 想请问下权限的控制 谢谢
- com+ 组件问题:462--远程服务不存在或找不到
- 如何用vb开发网络检测软件,功能不多,就两个,禁止qq和指定网页
- 请问在VB中如何得到系统的年,月,日
- 打印字体问题,在线等待,请进!
- 关于DataGrid控件的问题.可有对其具体单元格进行操做的事件和方法.
- 兄弟们,我的机子中毒了,谁告诉我解决,我给分》在线等候
- 求助,谁有读取access2000中的ole形式存的word文档,并存为临时的word文件的类似原程序???
- 避免同一时间对一个COM口传送数据有什么方法吗?急!
- 请问INET控件如何判断一个FTP的文件夹是否存在?
- 请问采用VB程序读写Excel怎么解决如下问题?
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",然后把收到的数据比较一下,要是发现是这个标记就说明收完了
发送端可以偷懒,不用主动分包。接收端必须进行包的合并处理。
约定采用先发送一个长度再发数据的方式比较好,不用处理特殊标志(接收缓冲区会出现多个数据包共存的情况,特殊标志只能靠全文搜索而不能直接定位)。
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不知你们这一块是怎么弄法的?给点高见
有效数据=UBound(bd)+1
因为这代码中,下标是0开始的。
这个结果,跟你的“实收”才相符。
你要是每次都把有效数据量少算1字节,
多次累计下来,已经差得比较多了,
最严重的是,你这样造成了数据没办法还原,
记录集不能“重建”(或重建后记录集是错的)。
客户端 bytesTotal=3825 UBound(bd)=3824多出来的一位是结束符吗?
Debug.Print "发送记录集:" & UBound(RsToBin(rs)) & " " & LenB(RsToBin(rs))
SockServer(Index).SendData RsToBin(rs)
UBound(bd)=3824 实际数据长度是3825,知道吗
上限是从0开始的 自己用手指从0数到9看看是多少
两边都是常规操作。谢谢以上各位了,现在能用就行了,有时间再研究一下