| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6751 人关注过本帖
标题:VB winsock接收数据处理的问题
取消只看楼主 加入收藏
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 23楼 lianyicq
对于你提出的问题,回答如下:
1;只有在12byte头包中的5-8位是本次查询回传数据总长度,后面的包中只包含数据,除最后的包以EN&VBCRLF&2byte校验值结尾外,没有任何标志。
2;5-8位是低位在前,高位在后的,而且这个顺序也有命令可以设置的。

如果你电脑上面装有Wireshark这个软件的话,可以下载一下18楼的附件,里面有整个数据返回时的抓包数据。
为了方便分析问题,我将抓包的数据转换成了TXT文档,并在相关内容后面加了注释。请参考附件。
HEX DATA.rar (20.09 KB)


[ 本帖最后由 hcyang1422 于 2015-5-5 10:25 编辑 ]
2015-05-05 09:55
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 25楼 lianyicq
不是单包可以发送完的,
你写的非单包数据格式基本正确,
不对的地方有以下3点
1:头包只有12byte,不包含数据
2:倒数第二包是以EN&VBCRLF结尾
3:最终的尾包只有2byte,即数据校验和
2015-05-05 10:58
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 27楼 lianyicq
已按给出的方案修正了代码并测试了,有以下问题
1:当程序初始化过程中发送查询命令时,只能接收到19K的数据,前面的8K丢失了。
2:程序运行过程中再次发送查询命令时,数据可以全部接收,但是会累计在之前的数据后面。
   即重新接收数据时,在新建临时文件前的Kill "c:\temp.dat"命令没有运行。
3:Select Case id 没有运行,而且id的值也随着新数据包在变化,不能固定取值为头包中的值。
现贴出全部接收代码,请再帮忙看看
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim S, S3, s1, flag, flag1 As String
Dim id, strlen As Integer
Dim tmp As String
Dim str() As Byte
Dim temp() As Byte
Dim FileByte() As Byte

ReDim str(bytesTotal - 1)                                                                  '初始化接收缓冲区

Winsock1.getData str, vbByte + vbArray
Select Case ReceiveState
  Case Is = True
    If str(UBound(str)) = &HA And str(UBound(str) - 1) = &HD And str(UBound(str) - 3) = Asc("E") And str(UBound(str) - 2) = Asc("N") Then
         ReDim FileByte(UBound(str) - 4)
         CopyMemory FileByte(0), str(0), UBound(str) - 3
         Put #1, , FileByte
         ReceiveState = False
         Select Case id
           Case Is = 19                                                   '当id为19时,表示接收的为设定信息
             '显示信息
             tmp = Mid(StrConv(1, vbUnicode), 6000, 10000)                '将全部查询数据转换为字符串,并截取中间部分
               S3 = Split(tmp, "ST", , vbBinaryCompare)                   '字符串分解,区分大小写
                'Text4.Text = Trim(s3)
                For i = 1 To UBound(S3)
                    s1 = Split(Split(S3(i), vbCrLf)(0), ",")(1)           '取通道标记
                    s1 = Trim(s1)
                    Text2 = Text2 + s1 + vbCrLf
                    Form4.CHNAME(j - 1) = Trim(s1)                        
                Next i
         End Select
         Close #1
       Else
         Put #1, , str
    End If
    Case Is = False
    flag = Chr(str(0)) & Chr(str(1))
   
        Select Case flag
           
           Case "E1"                                        '登录
              Sleep 200
              Login   '登录
              log.Text = log.Text & Format(Hour(Time), "00") & ":" & Format(Minute(Time), "00") & ":" & Format(Second(Time), "00") & " " & "admin" & vbCrLf  '显示日志
        
          Case "E0"
               u = u + 1
               log.Text = log.Text & Format(Hour(Time), "00") & ":" & Format(Minute(Time), "00") & ":" & Format(Second(Time), "00") & " " & strdata   '显示日志
               log.SelStart = Len(log.Text)
                If u = 1 Then
            '     Sleep 500
                log.Text = log.Text & Format(Hour(Time), "00") & ":" & Format(Minute(Time), "00") & ":" & Format(Second(Time), "00") & " " & "登录成功" & vbCrLf   '显示日志
                state_lab = "TCP/IP Connect OK"                  '登录成功
                log.SelStart = Len(log.Text)
                End If
          Case "EA"                                         '温度值返回
               S = strdata
               log.Text = log.Text                          '不显示日志
               log.SelStart = Len(log.Text)
                S3 = Split(S, "^C", , vbTextCompare)
                For j = 1 To UBound(S3)
                    s1 = Split(S3(j), vbCrLf)(0)
                    s1 = Trim(s1)
                    If Format(s1) > Val(Form4.CH(j - 1)) Then
                    Form4.CH(j - 1) = Format(s1, "00.0")
                    End If
                Next j
           Case "EB"                                         '二进制数据返回,
               If ReceiveState = False Then
                     Kill "c:\temp.dat"
                     Sleep 100
                     Open "c:\temp.dat" For Binary As #1
                     ReceiveState = True
                     id = str(9)
                     Exit Sub
                  End If
          End Select
End Select
End Sub

[ 本帖最后由 hcyang1422 于 2015-5-5 18:59 编辑 ]
2015-05-05 18:55
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 29楼 lianyicq
现在我在代码判断包头Case "EB"部分加了写入数据后,现在已可以接收全部数据了,
但是数据接收完成后的Select Case id部分仍然没有运行。
为判断原因,我在取id后加入了debug语句查看了取值的结果,发现结果是正确的,
请再帮忙看看是什么原因造成的。
2015-05-06 10:40
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 31楼 lianyicq
把id定义为全局变量后依然不行。是否应该把这部分的判断处理放在if语句外面,即先接收数据,当数据全部接收完成后,再进行处理。
2015-05-06 11:20
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 33楼 lianyicq
现在我把代码又修正了一下,红色字体的代码也可以执行了,而且id值也是正确的,即id=19
但是后面的处理程序没有正常工作,即下面红色字体处,该怎样才能把刚收到的全部数据转换成字符串进行处理?
现在的代码输出的tmp值为空。
Select Case id
           Case Is = 19                                                   '当id为19时,表示接收的为设定信息
             '显示信息
             tmp = Mid(StrConv(1, vbUnicode), 6000, 10000)                '将全部查询数据转换为字符串,并截取中间部分
             text7.text = tmp

               S3 = Split(tmp, "ST", , vbBinaryCompare)                   '字符串分解,区分大小写
                'Text4.Text = Trim(s3)
                For i = 1 To UBound(S3)
                    s1 = Split(Split(S3(i), vbCrLf)(0), ",")(1)           '取通道标记
                    s1 = Trim(s1)
                    Text2 = Text2 + s1 + vbCrLf
                    Form4.CHNAME(j - 1) = Trim(s1)                        
                Next i
         End Select

[ 本帖最后由 hcyang1422 于 2015-5-6 14:56 编辑 ]
2015-05-06 14:32
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 35楼 lianyicq
这个问题我已修正了,现在的问题是后面的处理程序没有正常工作,即下面红色字体处,该怎样才能把刚收到的全部数据转换成字符串进行处理?
现在的代码输出的tmp值为空。
Select Case id
           Case Is = 19                                                   '当id为19时,表示接收的为设定信息
             '显示信息
             tmp = Mid(StrConv(1, vbUnicode), 6000, 10000)                '将全部查询数据转换为字符串,并截取中间部分
             text7.text = tmp

               S3 = Split(tmp, "ST", , vbBinaryCompare)                   '字符串分解,区分大小写
                'Text4.Text = Trim(s3)
                For i = 1 To UBound(S3)
                    s1 = Split(Split(S3(i), vbCrLf)(0), ",")(1)           '取通道标记
                    s1 = Trim(s1)
                    Text2 = Text2 + s1 + vbCrLf
                    Form4.CHNAME(j - 1) = Trim(s1)                        
                Next i
         End Select
2015-05-06 15:16
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 37楼 lianyicq
现在的程序是把temp.bat做为动态数组保存接收数据的吧!并没有哪一个临时数组里面是包含全部数据的。现在我要调用已接收的全部数据,应怎么把temp.bat中的数据调入一个临时数组里面?

可以在接收完数据后,关闭temp.bat,然后再打开,用Get #2, , tmp语句进行全部数据调用吗?
2015-05-06 15:47
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 39楼 lianyicq
非常感谢你一直以来的帮助,刚才这一问题我用先关闭再打开的方法也搞定了,你的这种方法等下我再去测试一下。
另外,再向你请教一个比较小白的问题
我在这个处理过程中,得出的结果是传送给另外一个窗口的LABEL的Caption,我第一次点击显示子窗口时,可以看到得到的值,但是关掉后再打开,这个属性值又返回为默认值了。
请问如何才可以在得到数据后,将值锁定给子窗口的LABEL。
2015-05-06 16:10
hcyang1422
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2015-4-23
收藏
得分:0 
回复 41楼 lianyicq
用HIDE的方法把这个问题搞定了,非常感谢!!
后面我还要尝试读出图片数据,如果遇到问题还要继续向你请教,
还望能继续帮助我。
谢谢!!!
2015-05-06 16:44
快速回复:VB winsock接收数据处理的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030228 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved