IM(Socket)编程--ProtocolBuffer数据通信

进行Socket编程, 常见使用的协议UDP/TCP
TCP:传输控制协议 。是专门设计用于在不可靠的因特网上提供可靠的,端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
UDP:用户数据报协议 。不需要建立连接,不可靠。

iOS中Socket编程
●BSD Socket
BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制。在我们iOS中也可以使用,但是它所有的函数都是基于C语言的,所有在实际的项目开发中,我们都是使用封装好的。
●CFSocket
CFSocket是苹果官方提供给我们进行Socket编程,里面还是有很多C语言的东西,使用起来稍微麻烦一点。
●AsyncSocket
AsyncSocket是一个开源的库,用来进行iOS的Socket编程就非常方便, 但是目前只有OC版本, 并且长时间没有更新
●ysocket
目前使用Swift进行Socket编程时,常用的一个库

消息传输
TCP在传输数据时,传输的是字节流
在读取消息时,需要知道数据的长度, 否则就会出现读取不完整或者读取长度过多的情况, 因此读取方法要求我们传入本次读取的消息长度
如何解决该问题呢?
方案一: 客户端发送两次消息
消息一是记录后续消息长度, 消息二是真正的消息

1672235-d169fdcc667c10a0.png
1.png

方案二: 客户端发送一次消息
消息有一个Header,用于记录消息的长度, 后续为真实消息内容
1672235-11a49f47f86779e8.png
2.png

消息类型
开发中经常遇到类似这样的场景:
我们的客户端是使用Swift/OC/Java来写的, 可以运行在不同的平台, iOS/Android/Window/Linux.服务器基于Linux平台并使用C++开发完成的, 两种程序之间采用什么进行通信呢?

  • 直接传递C/C++语言中一字节对齐的结构体数据,只要结构体的声明为定长格式,那么该方式对于C/C++程序而言就非常方便了, 但是对于java这种不常用结构体的语言, 处理起来就相当麻烦
  • 使用SOAP协议(WebService)作为消息报文的格式载体,由该方式生成的报文是基于文本格式的,同时还存在大量的XML描述信息,因此将会大大增加网络IO的负担。又由于XML解析的复杂性,这也会大幅降低报文解析的性能。总之,使用该设计方式将会使系统的整体运行性能明显下降。
  • Json交换格式, 目前比较理想的一种通信格式, 也是在Http请求数据时, 最常见的用法(Demo程序)
  • ProtocolBuffer(也称PB/GPB): google 的一种数据交换的格式, 可以实现跨平台, 方便的序列化&反序列化, 并且数据量相对json

Json/GPB对比优缺点对比

  • 跨平台
    ProtoBuf支持多平台和语言, 包括C++/Java/Python等等
  • 序列化&反序列号
    ProtoBuf支持直接将对象序列化成Data, 也支持直接将Data序列化为对象类型
  • 消息大小
    一条消息数据,用protobuf序列化后的大小是json的10分之一xml格式的20分之一,是二进制序列化的10分之一
    对于即时通信消息来说, 减小数据量的大小非常有必须

主题:
ProtocolBuffer使用
1.ProtocolBuffer环境安装
How To Install Protobuf Compiler from Homebrew

1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.brew install protobuf-swift
How To Install Protobuf Compiler
1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2.brew install automake

3.brew install libtool

4.brew install protobuf

5.git clone git@github.com:alexeyxo/protobuf-swift.git

6../scripts/build.sh

Add ./src/ProtocolBuffers/ProtocolBuffers.xcodeproj in your project.

2.ProtocolBuffer的使用

2.1 创建.proto文件
在项目中, 创建一个(或多个).proto文件
之后会通过该文件, 自动帮我们生成需要的源文件(比如C++生成.cpp源文件, 比如java生成.java源文件, Swift就生成.swift源文件)


1672235-a723894306255694.jpg
3.jpg
1672235-41919731c6886744.png
4.png

源码规范

syntax = "proto2";
message GiftMessage {
    required int64 id = 1;
    required string name = 2;
    optional string email = 3;
}

具体说明

● syntax = "proto2"; 为定义使用的版本号, 目前常用版本proto2/proto3
● message是消息定义的关键字,等同于C++/Swift中的struct/class,或是Java中的class
● Person为消息的名字,等同于结构体名或类名
● required前缀表示该字段为必要字段,既在序列化和反序列化之前该字段必须已经被赋值
● optional前缀表示该字段为可选字段, 既在序列化和反序列化时可以没有被赋值
● repeated通常被用在数组字段中
● int64和string分别表示整型和字符串型的消息字段
● id和name和email分别表示消息字段名,等同于Swift或是C++中的成员变量名
● 标签数字1和2则表示不同的字段在序列化后的二进制数据中的布局位置, 需要注意的是该值在同一message中不能重复

2.2 .代码编写完成后, 生成对应语言代码
cd +文件夹目录
protoc 文件名.proto --swift_out="./“

 protoc IMText.proto --swift_out="./“

3.用法:

 //1.创建giftMsg 
   let giftMsg = GiftMessage.Builder()
   giftMsg.giftname  = giftname
   giftMsg.giftUrl = giftURL
   giftMsg.giftCount = giftCount
        
//2.获取对应的data
   let giftData = (try! giftMsg.build()).data() 
//3.发送礼物消息
   sendMsg(data: giftData, type: 3)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值