進行Socket編程, 常見使用的協(xié)議UDP/TCP
TCP:傳輸控制協(xié)議 。是專門設(shè)計用于在不可靠的因特網(wǎng)上提供可靠的,端到端的字節(jié)流通信的協(xié)議。它是一種面向連接的協(xié)議。TCP連接是字節(jié)流而非報文流。
UDP:用戶數(shù)據(jù)報協(xié)議 。不需要建立連接,不可靠。
iOS中Socket編程
●BSD Socket
BSD Socket 是UNIX系統(tǒng)中通用的網(wǎng)絡(luò)接口,它不僅支持各種不同的網(wǎng)絡(luò)類型,而且也是一種內(nèi)部進程之間的通信機制。在我們iOS中也可以使用,但是它所有的函數(shù)都是基于C語言的,所有在實際的項目開發(fā)中,我們都是使用封裝好的。
●CFSocket
CFSocket是蘋果官方提供給我們進行Socket編程,里面還是有很多C語言的東西,使用起來稍微麻煩一點。
●AsyncSocket
AsyncSocket是一個開源的庫,用來進行iOS的Socket編程就非常方便, 但是目前只有OC版本, 并且長時間沒有更新
●ysocket
目前使用Swift進行Socket編程時,常用的一個庫
消息傳輸
TCP在傳輸數(shù)據(jù)時,傳輸?shù)氖亲止?jié)流
在讀取消息時,需要知道數(shù)據(jù)的長度, 否則就會出現(xiàn)讀取不完整或者讀取長度過多的情況, 因此讀取方法要求我們傳入本次讀取的消息長度
如何解決該問題呢?
方案一: 客戶端發(fā)送兩次消息
消息一是記錄后續(xù)消息長度, 消息二是真正的消息
方案二: 客戶端發(fā)送一次消息
消息有一個Header,用于記錄消息的長度, 后續(xù)為真實消息內(nèi)容
消息類型
開發(fā)中經(jīng)常遇到類似這樣的場景:
我們的客戶端是使用Swift/OC/Java來寫的, 可以運行在不同的平臺, iOS/Android/Window/Linux.服務(wù)器基于Linux平臺并使用C++開發(fā)完成的, 兩種程序之間采用什么進行通信呢?
- 直接傳遞C/C++語言中一字節(jié)對齊的結(jié)構(gòu)體數(shù)據(jù),只要結(jié)構(gòu)體的聲明為定長格式,那么該方式對于C/C++程序而言就非常方便了, 但是對于java這種不常用結(jié)構(gòu)體的語言, 處理起來就相當麻煩
- 使用SOAP協(xié)議(WebService)作為消息報文的格式載體,由該方式生成的報文是基于文本格式的,同時還存在大量的XML描述信息,因此將會大大增加網(wǎng)絡(luò)IO的負擔。又由于XML解析的復雜性,這也會大幅降低報文解析的性能。總之,使用該設(shè)計方式將會使系統(tǒng)的整體運行性能明顯下降。
- Json交換格式, 目前比較理想的一種通信格式, 也是在Http請求數(shù)據(jù)時, 最常見的用法(Demo程序)
- ProtocolBuffer(也稱PB/GPB): google 的一種數(shù)據(jù)交換的格式, 可以實現(xiàn)跨平臺, 方便的序列化&反序列化, 并且數(shù)據(jù)量相對json
Json/GPB對比優(yōu)缺點對比
- 跨平臺
ProtoBuf支持多平臺和語言, 包括C++/Java/Python等等- 序列化&反序列號
ProtoBuf支持直接將對象序列化成Data, 也支持直接將Data序列化為對象類型- 消息大小
一條消息數(shù)據(jù),用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二進制序列化的10分之一
對于即時通信消息來說, 減小數(shù)據(jù)量的大小非常有必須
主題:
ProtocolBuffer使用
1.ProtocolBuffer環(huán)境安裝
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 創(chuàng)建.proto文件
在項目中, 創(chuàng)建一個(或多個).proto文件
之后會通過該文件, 自動幫我們生成需要的源文件(比如C++生成.cpp源文件, 比如java生成.java源文件, Swift就生成.swift源文件)
3.jpg
4.png
源碼規(guī)范
syntax = "proto2";
message GiftMessage {
required int64 id = 1;
required string name = 2;
optional string email = 3;
}
具體說明
● syntax = "proto2"; 為定義使用的版本號, 目前常用版本proto2/proto3
● message是消息定義的關(guān)鍵字,等同于C++/Swift中的struct/class,或是Java中的class
● Person為消息的名字,等同于結(jié)構(gòu)體名或類名
● required前綴表示該字段為必要字段,既在序列化和反序列化之前該字段必須已經(jīng)被賦值
● optional前綴表示該字段為可選字段, 既在序列化和反序列化時可以沒有被賦值
● repeated通常被用在數(shù)組字段中
● int64和string分別表示整型和字符串型的消息字段
● id和name和email分別表示消息字段名,等同于Swift或是C++中的成員變量名
● 標簽數(shù)字1和2則表示不同的字段在序列化后的二進制數(shù)據(jù)中的布局位置, 需要注意的是該值在同一message中不能重復
2.2 .代碼編寫完成后, 生成對應語言代碼
cd +文件夾目錄
protoc 文件名.proto --swift_out="./“
protoc IMText.proto --swift_out="./“
3.用法:
//1.創(chuàng)建giftMsg
let giftMsg = GiftMessage.Builder()
giftMsg.giftname = giftname
giftMsg.giftUrl = giftURL
giftMsg.giftCount = giftCount
//2.獲取對應的data
let giftData = (try! giftMsg.build()).data()
//3.發(fā)送禮物消息
sendMsg(data: giftData, type: 3)