玩转socket之字节流操作--拼包、拆包

本文探讨在使用socket进行TCP/IP自定义协议开发时,字节流操作的重要性。讲解了NSData/Data、字节数组、十六进制字符串、字节序、编码和解码方式等方面,提供了Objective-C和Swift的实现示例,包括整型、浮点型、字符串的编码和解码,以及C结构体的传输。并指出在Swift 5中处理字节流时的注意事项和解决方法。
摘要由CSDN通过智能技术生成
玩转socket之字节流操作--拼包、拆包

我们开发中用得最多的HTTP协议及超文本传输协议,是一种基于TCP/IP的文本传输协议。基本很少碰到字节流操作。

但是我过我们要用socket,实现一套基本TCP/IP协议的自定义协议,那么,对于字节流的操作,数据包的拼接、拆解,是绕不开的。

本文的所有示例代码在这里

字节流的表示方式
NSData、Data

在iOS,对于字节流,大多数情况下我们要打交道的是NSData类型数据。在swift中它叫Data

字节数组

在OC中它可以表示为Byte类型的数组

Byte bytes[256];
复制代码

Byte等同于UInt8unsigned char

typedef UInt8            Byte;
typedef unsigned char    UInt8;
复制代码

与NSData相互转换:

// bytes转Data
Byte bytes[256] = {0xff,0xaa,0x33,0xe4};
NSData *data = [[NSData alloc] initWithBytes:bytes length:256];

// Data转Bytes
const Byte *nBytes = [data bytes];
// 或者
Byte byte[4] = {0};
[cdata getBytes:byte length:4];
复制代码

swift中,没有Byte类型,他叫[UInt8]。转化为Data

var bytes : [UInt8] = [0x22,0xef,0xee,0xb3]
let data = Data(bytes)
复制代码

DataUInt8时,没有像OC一样的bytes方法

我们也可以跟OC中类似的方法

var nBytes = [UInt8]()
data.copyBytes(to:&nBytes, count:4)
复制代码

当然,最简单的方式是这样

let bytes = [UInt8](data)
复制代码

如果你喜欢,也可以这样

let bytes : [UInt8] = data0.withUnsafeBytes({
   $0.map({
   $0})})
复制代码
十六进制字符串

我们都知道,计算机存储和传输的数据都是二进制的。而二进制不易与阅读。当我们要查看字节流进行调试时,往往会将其转化为16进制的字符串。

OC的NSData对象打印默认得到的是带*<>*及空格的十六进制字符串。如果想让其根容易阅读些,可以在NSData的category中增添:

- (NSString *)hexString
{
    NSMutableString *mstr = [NSMutableString new];
    const Byte *bytes = [self bytes];
    for (int i = 0; i < self.length; i++) {
        [mstr appendFormat:@"0x%02x ",bytes[i]];
    }
    return mstr;
}
复制代码

swift中的Data只能打印出有多少个字节。需要一个生成十六进制串的方法:

extension UInt8 {
    var hexString : String {
        let str = String(format:"0x%02x",self)
        return str
    }
}

extension Data {
    var bytes : [UInt8] {
        return [UInt8](self)
    }
    var hexString : String {
        var str = ""
        for byte in self.bytes {
            str += byte.hexString
            str += " "
        }
        return str
    }
}
复制代码
字节序

在进行字节流的拼接和解析之前,我们必须先了解网络传输中,一个关键的概念字节序

什么叫字节序

当一个整数的值大于255时,必须用多个字节表示。那么就产生一个问题,这些字节是从左到右还是从右到左称为字节顺序。

大端字节序Vs小端字节序

如果我们有一个16进制值0x0025,那么它包含两个字节0x00、0x25。在传输时,我们期望的是,在字节流中,先看到0x00而0x25紧随其后。

如果是大端

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值