新建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个请求也会循环提示,所以必须读!