一个 TCP 拆包 器

Public Function GetMsgNote(bReceive() As Byte, Optional GSM_OR_GPRS As String = "GPRS", Optional islast As Integer) As Boolean
    '
    'Meaning:最新解析数据包过程
    'Date:2004-05-04
    'Author:  这里不能出现原作者的名字,免得惹麻烦
    Dim i As Long, j As Long
    Dim sTemp As String
    Dim XorResult As Integer
    Dim aMsgNote() As Byte '组合数据包
    Dim sMsgNote() As Byte '合法数据包
    Dim iMsgType As Integer
    Dim M_Doevents_Flag As Boolean
 
    On Error GoTo GetMsgNoteErr
    '//
    '判断上一次是否有没有解析的包,若有则组合数据包
    If GSM_OR_GPRS = "GPRS" Then
        If UBound(g_tMsgNote) = 0 Then
            ReDim aMsgNote(UBound(bReceive))
            aMsgNote = bReceive
        Else
            ReDim aMsgNote(UBound(g_tMsgNote) + 1 + UBound(bReceive))
            For i = 0 To UBound(g_tMsgNote)
                aMsgNote(i) = g_tMsgNote(i)
            Next
            For i = 0 To UBound(bReceive)
                aMsgNote(i + UBound(g_tMsgNote) + 1) = bReceive(i)
            Next
            ReDim g_tMsgNote(0)
        End If
 
    Else
        ReDim aMsgNote(UBound(bReceive))
        aMsgNote = bReceive
    End If
    For i = 0 To UBound(aMsgNote)
 
        '/
        '判断包中没有解析的数据的长度是否大于或等于4,大于或等于4是因为要读包头、信令类型、包长
        If UBound(aMsgNote) - i >= 4 Then
            '
            '找单个数据包的包头      
            If (aMsgNote(i) = 41 And aMsgNote(i + 1) = 41) Or (aMsgNote(i) = 36 And aMsgNote(i + 1) = 36) Then   '兼容协议
                '/
                '判断包中没有解析的数据的长度是否大于或等于包长加4,加4是因为要读包头、信令类型、包长有5位
                If (UBound(aMsgNote) - i) >= (aMsgNote(i + 3) * 256 + aMsgNote(i + 4) + 4) Then
                 '兼容协议
 
                            '//
                            '从数据包中分离出包尾为0A的单个数据包
                            ReDim sMsgNote(aMsgNote(i + 3) * 256 + aMsgNote(i + 4) + 4)
                            For j = 0 To UBound(sMsgNote)
                                sMsgNote(j) = aMsgNote(i + j)
                            Next
                            '
                            '根据数据包的校验和检测包的正确性
                            XorResult = sMsgNote(2)
                            For j = 3 To UBound(sMsgNote) - 2
                                XorResult = XorResult Xor sMsgNote(j)
                            Next
                            '//
                            '若异或结果等于校验和,则解析这个数据包
                            If XorResult = sMsgNote(UBound(sMsgNote) - 1) Then
                                '/
                                '解析单个数据包(sMsgNote)
                                iMsgType = GetMsgType(sMsgNote, GSM_OR_GPRS)
                                
                                '//
                                '将i的位置移动到下当前记录的末尾
                                i = i + UBound(sMsgNote)
                            End If
       
                Else
                    '数据包不全,或剩余包不全,保留剩余包退出循环
                     
                        ReDim g_tMsgNote(UBound(aMsgNote) - i)
                        For j = 0 To UBound(aMsgNote) - i
                            g_tMsgNote(j) = aMsgNote(i + j)
                        Next
                        Exit For
                   
                End If
            End If
        Else
            '数据包不全,或剩余包不全,保留剩余包退出循环
           
                ReDim g_tMsgNote(UBound(aMsgNote) - i)
                For j = 0 To UBound(aMsgNote) - i
                    g_tMsgNote(j) = aMsgNote(i + j)
                Next
                Exit For
            
        End If
    Next
      
    GetMsgNote = True '解包成功函数返回1
    Erase aMsgNote
    Erase sMsgNote
    Exit Function
GetMsgNoteErr:     
    GetMsgNote = False '解包错误函数返回0
    Exit Function
End Function




第一次收到:24 24 57 00 29 E8 3A 94 84 04 12 15 43 09 02 93 22 39 10 63 07 02 00 00 02 09 C9 05 00 00 01 00 FF 32 AA AA 00 00 22 D0 00 00 94 A4 C0 0A 

第二次收到:24 24 57 00 29 ED 75 C5 D2 04 12 15 43 11 02 93 32 45 10 63 23 68 00 14 02 60 C8 05 00 00 01 00 FF 23 AA AA 00 00 2E 4B 00 00 C8 88 3D 0A 24 24 57 00 29 E8 3A B4 2D 04 12 15 43 11 02 92 80 39 10 63 23 53 00 22 00 08 C8 05 00 00 01 00 FF 32 20 F4 00 00 39 BC 00 00 EB 4C 93 0A 24 24 57 00 21 D0 A3 91 5B 04 12 15 42 48 02 93 65 01 10 63 26 84 00 00 00 78 C6 05 00 00 01 00 00 32 00 01 6B 0A 24 24 57 00 21 D0 A3 91 5B 04 12 15 43 08 02 93 65 02 10 63 26 85 00 00 00 78 C9 05 00 00 01 00 00 32 00 01 27 0A 24 24 57 00 29 E8 39 57 4F 04 12 15 43 11 02 93 04 97 10 63 42 07 00 00 00 00 D4 05 00 00 01 00 FF 3C 38 AA 00 00 04 48 00 00 0D 05 17 0A 24 24 57 00 29 E8 39 48 8F 04 12 15 43 11 02 92 94 99 10 62 89 82 00 09 01 77 C7 05 00 00 01 00 E7 32 AA AA 00 00 01 E4 00 00 2E F5 8A 0A 24 24 57 00 29 D8 D5 1A 67 04 12 15 43 10 02 93 26 94 10 63 13 36 00 01 02 07 C8 05 00 00 01 00 EF 32 AA AA 00 00 00 54 00 00 15 01 7E 0A 24 24 57 00 29 ED 74 55 35 04 12 15 43 10 02 92 90 42 10 62 91 18 00 00 02 32 C9 05 00 00 01 00 FF 32 AA AA 00 00 09 0D 00 00 25 DF A0 0A 24 24 57 00 29 ED 75 F1 17 04 12 15 43 10 02 93 66 27 10 63 02 55 00 00 03 23 10 05 00 00 01 00 FF 32 AA AA 00 00 09 F6 00 00 29 00 8B 0A 24 24 45 00 1E D8 D3 8D 9B 04 12 15 43 09 00 AA CA 14 48 01 2C 00 00 01 2C 00 00 00 00 25 CA 9E 03 41 0A 24 24 57 00 29 ED 76 75 D2 04 12 15 43 11 02 93 48 72 10 63 37 58 00 11 03 17 C9 05 00 00 01 00 FF 28 AA AA 00 00 3E 7C 00 00 FC 7F 7A 0A 24 24 57 00 29 E8 39 44 80 04 12 15 43 11 02 93 23 80 10 63 35 88 00 00 01 76 CB 05 00 00 01 00 EF 32 AA AA 00 00 01 2C 00 00 2A 06 A2 0A 24 24 57 00 29 CD C2 F2 6C 04 12 15 43 10 02 95 19 68 10 62 37 20 00 01 02 40 C7 05 00 00 01 00 FF 32 AA AA 00 00 3A 96 00 00 F9 2B 0F 0A 24 24 57 00 29 ED 74 4D 90 04 12 15 43 11 02 93 16 12 10 62 90 74 00 00 00 65 C8 05 00 00 01 00 FF 37 AA AA 00 00 4B 9C 00 00 BF 28 49 0A 24 24 57 00 29 E8 3A 90 8C 04 12 15 43 10 02 93 13 96 10 63 16 02 00 35 02 71 C8 05 00 00 01 00 FF 32 AA AA 00 00 3B 1D 00 00 FD BC B3 0A 24 24 57 00 29 CD CD 95 15 04 12 15 43 09 02 93 37 38 10 62 83 21 00 00 02 81 C9 05 00 00 01 00 E7 32 AA AA 00 00 01 5A 00 00 2D 4E 5A 0A 24 24 57 00 29 ED 75 DF 2A 04 12 15 43 11 02 93 39 85 10 63 49 01 00 06 02 35 C6 05 00 00 01 00 FF 32 AA AA 00 00 3C BA 00 01 03 C6 28 0A 24 24 57 00 29 ED 74 6E E2 04 12 15 43 09 02 94 05 27 10 61 81 63 00 04 01 39 C6 05 00 00 01 00 FF 32 AA AA 00 00 36 5D 00 00 7F 9E BC 0A 24 24 57 00 29 ED 75 BA AE 04 12 15 43 23 02 93 18 25 10 63 28 07 00 00 00 00 10 05 00 00 01 00 FF 32 AA AA 00 00 29 D7 00 00 B7 30 C1 0A 24 24 57 00 29 ED 76 4F A5 04 12 15 43 11 02 93 49 76 10 63 35 40 00 25 03 37 C6 05 00 00 01 00 FF 28 AA AA 00 00 3A B1 00 00 FF 69 EF 0A 24 24 57 00 29 ED 75 DC DD 04 12 15 43 11 02 93 47 14 10 62 57 90 00 10 00 08 C8 05 00 00 01 00 FF 32 AA AA 00 00 27 E5 00 00 A0 AF 15 0A 24 24 57 00 29 CD C2 F2 79 04 12 15 43 10 02 94 94 08 10 62 60 28 00 00 03 16 C9 05 00 00 01 00 FF 32 AA AA 00 00 35 61 00 00 D4 CC C3 0A 24 24 57 00 29 ED 75 F6 DE 04 12 15 43 10 02 93 26 09 10 63 08 16 00 25 02 63 C4 05 00 00 01 00 FF 32 AA AA 00 00 3E 5E 00 01 08 16 7B 0A 24 24 57 00 29 ED 75 9F C3 04 12 15 43 11 02 93 09 75 10 63 07 76 00 01 02 02 C6 05 00 00 01 00 FF 32 AA AA 00 00 40 13 00 01 01 30 69 0A 24 24 45 00 1E D8 D3 8D C0 04 12 15 43 10 00 AA C8 14 48 01 2C 00 00 01 2C 00 00 00 00 25 CA 9E 28 2A 0A 24 24 57 00 29 CD CD A6 BD 04 12 15 43 11 02 93 40 28 10 63 32 22 00 06 02 23 D3 05 00 00 01 00 FF 32 AA AA 00 00 01 8B 00 00 34 37 1A 0A 24 24 57 00 29 EE 2F CA A4 04 12 15 43 11 02 93 37 49 10 62 82 76 00 00 02 89 C9 05 00 00 01 00 FF 32 AA AA 00 00 41 2D 00 01 16 00 19 0A 24 24 57 00 29 DF AF 9D C3 04 12 15 43 10 02 93 05 63 10 63 05 59 00 00 01 87 C6 05 00 00 01 00 FF 28 AA AA 00 00 16 E2 00 00 A4 39 22 0A 24 24 57 00 29 E8 3A 90 73 04 12 15 43 10 02 93 26 12 10 62 76 39 00 17 02 28 C4 05 00 00 01 00 FF 32 AA AA 00 00 16 21 00 01 2C B0 1D 0A 24 24 57 00 29 E8 3A 98 4D 04 12 15 43 11 02 93 02 50 10 63 04 37 00 00 02 12 C5 05 00 00 01 00 FF 28 AA F4 00 00 27 C5 00 00 8E 71 EE 0A 24 24 57 00 29 ED 76 26 E3 04 12 15 43 10 02 93 55 68 10 63 12 26 00 38 01 64 D4 05 00 00 01 00 FF 32 AA AA 00 00 31 C6 00 00 D7 E2 19 0A 

数据是以24 24(16进制)开始,以0A结束。 这个是接收到的一个完整的数据包。 期间可能包括很多条数据。 
其中14-17 四个字节代表纬度 如:02 93 34 65 

    18-21 四个字节代表经度 如:10 63 32 49 

解析后的结果应该是纬度在29 左右,经度在106左右。 





Netty中的TCP粘包和拆包问题是由于底层的TCP协议无法理解上层的业务数据而导致的。为了解决这个问题,Netty提供了几种解决方案。其中,常用的解决方案有四种[1]: 1. 固定长度的拆包(FixedLengthFrameDecoder):将每个应用层数据包拆分成固定长度的大小。这种拆包适用于应用层数据包长度固定的情况。 2. 行拆包(LineBasedFrameDecoder):将每个应用层数据包以换行符作为分隔符进行分割拆分。这种拆包适用于应用层数据包以换行符作为结束符的情况。 3. 分隔符拆包(DelimiterBasedFrameDecoder):将每个应用层数据包通过自定义的分隔符进行分割拆分。这种拆包适用于应用层数据包以特定分隔符作为结束标志的情况。 4. 基于数据包长度的拆包(LengthFieldBasedFrameDecoder):将应用层数据包的长度作为接收端应用层数据包的拆分依据。根据应用层协议中包含的数据包长度进行拆包。这种拆包适用于应用层协议中包含数据包长度的情况。 除了使用这些拆包,还可以根据业界主流协议的解决方案来解决粘包和拆包问题[3]: 1. 消息长度固定:累计读取到长度和为定长LEN的报文后,就认为读取到了一个完整的信息。 2. 使用特殊的分隔符:将换行符或其他特殊的分隔符作为消息的结束标志。 3. 在消息头中定义长度字段:通过在消息头中定义长度字段来标识消息的总长度。 综上所述,Netty提供了多种解决方案来解决TCP粘包和拆包问题,可以根据具体的业务需求选择合适的解决方案[1][3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值