iOS基礎(chǔ)通訊UDP/KCP協(xié)議的使用

我的demo地址:
https://github.com/caobo56/KCPDemo

什么是KCP郑藏?

kcp協(xié)議是傳輸層的一個具有可靠性的傳輸層ARQ協(xié)議。它的設(shè)計是為了解決在網(wǎng)絡(luò)擁堵情況下tcp協(xié)議的網(wǎng)絡(luò)速度慢的問題档冬。kcp力求在保證可靠性的情況下提高傳輸速度起趾。kcp協(xié)議的關(guān)注點主要在控制數(shù)據(jù)的可靠性和提高傳輸速度上面班巩,因此kcp沒有規(guī)定下層傳輸協(xié)議查近,一般用udp作為下層傳輸協(xié)議,kcp層協(xié)議的數(shù)據(jù)包在udp數(shù)據(jù)報文的基礎(chǔ)上增加控制頭语卤。當(dāng)用戶數(shù)據(jù)很大追逮,大于一個udp包能承擔(dān)的范圍時(大于mss),kcp會將用戶數(shù)據(jù)分片存儲在多個kcp包中粹舵。因此每個kcp包稱為一個分片钮孵。

為了提供可靠性,kcp采用了重傳機(jī)制眼滤。為實現(xiàn)重傳機(jī)制巴席,kcp為每個分片分配一個唯一標(biāo)識,接收方收到一個包后告知發(fā)送方接到的包的序號诅需,發(fā)送方接到確認(rèn)后再繼續(xù)發(fā)送漾唉。而如果發(fā)送方在一定時間內(nèi)(超時重傳時間)沒有接到確認(rèn),就說明數(shù)據(jù)包丟失了堰塌,發(fā)送方需要重傳丟失的數(shù)據(jù)包赵刑,所以發(fā)送方會把待確認(rèn)的數(shù)據(jù)緩存起來,方便重傳场刑。

個人理解:

個人理解:KCP 只是一種對UDP收發(fā)包的處理機(jī)制般此,并不具有通訊功能。需要額外的配置其底層的傳輸協(xié)議如UDP摇邦。另外恤煞,KCP是一種快速重傳的ARQ協(xié)議屎勘,因此施籍,需要使用KCP的節(jié)點,同時具有收發(fā)數(shù)據(jù)的功能概漱,以便KCP獲取到完整數(shù)據(jù)后發(fā)送接收完整的回調(diào)丑慎。
KCP的好處:就是比TCP浪費30%左右的帶寬,提升UDP的數(shù)據(jù)發(fā)送速度,并提升UDP的可靠性竿裂。

需要注意:

此外玉吁,需要說明的是,由于kcp需要在收到數(shù)據(jù)后腻异,給數(shù)據(jù)的發(fā)送方發(fā)送回執(zhí)消息进副。發(fā)送數(shù)據(jù)時,也要收取一個從服務(wù)端返回的發(fā)送成功回執(zhí)悔常。

所以影斑,一個正常運行的kcp-UDP節(jié)點,必然同時具備收取消息和發(fā)送消息的功能机打,因此矫户,我demo 里不再區(qū)分client 和 server 。

一個kcp節(jié)點残邀,必然既是客戶端皆辽,也是服務(wù)端。

kcp協(xié)議詳解

KCP C源代碼:
https://github.com/skywind3000/kcp

使用方法在KCPgithub 上寫的很清晰:

屏幕快照 2018-02-24 上午10.49.48.png
屏幕快照 2018-02-24 上午10.50.00.png

下面是我用OC 實現(xiàn)的簡單的KCP使用芥挣。
因為kcp協(xié)議的關(guān)注點主要在控制數(shù)據(jù)的可靠性和提高傳輸速度上面驱闷,所以,kcp沒有規(guī)定下層傳輸協(xié)議空免。只需要向KCP提供相應(yīng)的發(fā)送數(shù)據(jù)方法遗嗽,并實現(xiàn)獲取數(shù)據(jù)的回調(diào)方法即可。

因此鼓蜒,我選擇使用GCDAsyncUdpSocket 作為KCP 的下層UDP實現(xiàn):
實現(xiàn)代碼demo地址:
https://github.com/caobo56/KCPDemo

代碼結(jié)構(gòu):


屏幕快照 2018-02-24 上午11.05.18.png

另外需要注意的是痹换,項目中引入了ickp.h 和 ickp.c 兩個C文件,
因此在編譯的時候最好配置一下C的編譯設(shè)置:

TARGET -> BuildSetting -> C Language Dialect
屏幕快照 2018-02-24 上午11.07.55.png

最終的使用方式:

//
//  SendViewController.m
//  textDemo
//
//  Created by caobo56 on 18/2/22.
//  Copyright ? 2018年 caobo56. All rights reserved.
//

#import "SendViewController.h"

#import "KcpOnUdp.h"

/**
 *  客戶端
 */
@interface SendViewController ()<KcpOnUdpDelegate>
{
    __weak IBOutlet UITextField *msgTF;
    __weak IBOutlet UITextField *ipTF;
    __weak IBOutlet UILabel *receiveLab;
}

@property (nonatomic,strong)KcpOnUdp * netWork;

@end

@implementation SendViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"KcpOnUdp節(jié)點";
    _netWork = [KcpOnUdp creatKcpOnUdpWithPort:10099];
    //啟動KcpOnUdp 并設(shè)置啟動時的端口
    _netWork.delegate = self;
    //設(shè)置代理都弹,接受數(shù)據(jù)

}

#pragma mark 發(fā)送消息
- (IBAction)sendMsgClick:(UIButton *)sender {
    //向指定的 ip port 發(fā)送數(shù)據(jù)
    [_netWork sendMsg:msgTF.text toHost:ipTF.text toPort:10099];
}

#pragma mark KcpOnUdp delegate
//接收數(shù)據(jù)
-(void)kcpOnUdpDidReciveMsg:(NSString *)str{
    NSLog(@"kcpOnUdpDidReciveMsg = %@",str);
}

@end


此外娇豫,我用來跟客戶端/服務(wù)端 鏈接測試的例子是jkcp, https://github.com/beykery/jkcp
在開發(fā)調(diào)試過程中可以以此作為調(diào)試基準(zhǔn)進(jìn)行測試畅厢。
調(diào)試過程中注意客戶端服務(wù)端的kcp參數(shù)要保持一致冯痢,以下是我的配置:
server 配置:

        TestServer s = new TestServer(10099, 1);
        s.noDelay(1, 10, 2, 1);
        s.setMinRto(10);
        s.wndSize(128, 128);
        s.setTimeout(10 * 1000);
        s.setMtu(512);
        s.start();

clinet 配置:

    TestClient tc = new TestClient();
    tc.noDelay(1, 10, 2, 1);
    tc.setMinRto(10);
    tc.wndSize(128, 128);
    tc.setTimeout(10 * 1000);
    tc.setMtu(512);
    tc.setConv(121106);

iOS 端配置:

    //設(shè)置KCP參數(shù),同服務(wù)端或者對點端參數(shù)保持一致
    //特別是conv框杜,對方客戶端的conv 必須同自身服務(wù)端的conv一致
    int32_t conv = 121106;
    c_kcp = ikcp_create(conv, NULL);
    ikcp_nodelay(c_kcp, 1, 10, 2, 1);
    c_kcp->rx_minrto = 10;
    ikcp_wndsize(c_kcp, 128, 128);
    ikcp_setmtu(c_kcp, 512);

配置說明:

conv: 數(shù)字浦楣,123 這樣就可以,只需要保證 client.server 的數(shù)字是一樣就可以
user: 指針咪辱,給你自己傳遞參數(shù)用的振劳,你沒有特殊參數(shù)需要傳那就用 NULL

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市油狂,隨后出現(xiàn)的幾起案子历恐,更是在濱河造成了極大的恐慌寸癌,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弱贼,死亡現(xiàn)場離奇詭異蒸苇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吮旅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門溪烤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人庇勃,你說我怎么就攤上這事氛什。” “怎么了匪凉?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵枪眉,是天一觀的道長。 經(jīng)常有香客問我再层,道長贸铜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任聂受,我火速辦了婚禮蒿秦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛋济。我一直安慰自己棍鳖,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布碗旅。 她就那樣靜靜地躺著渡处,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祟辟。 梳的紋絲不亂的頭發(fā)上医瘫,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音旧困,去河邊找鬼醇份。 笑死,一個胖子當(dāng)著我的面吹牛吼具,可吹牛的內(nèi)容都是我干的僚纷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼拗盒,長吁一口氣:“原來是場噩夢啊……” “哼怖竭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锣咒,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤侵状,失蹤者是張志新(化名)和其女友劉穎赞弥,沒想到半個月后毅整,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趣兄,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年悼嫉,在試婚紗的時候發(fā)現(xiàn)自己被綠了艇潭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡戏蔑,死狀恐怖蹋凝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情总棵,我是刑警寧澤鳍寂,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站情龄,受9級特大地震影響迄汛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骤视,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一鞍爱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧专酗,春花似錦睹逃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佑笋,卻和暖如春拜轨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背允青。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工橄碾, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颠锉。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓法牲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親琼掠。 傳聞我的和親對象是個殘疾皇子拒垃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容