主頁 > 後端開發 > KCP協議學習

KCP協議學習

2022-01-06 17:17:17 後端開發

簡介

KCP是一個快速可靠協議,能以比 TCP 浪費 10%-20% 的帶寬的代價,換取平均延遲降低 30%-40%,且最大延遲降低三倍的傳輸效果,純演算法實作,并不負責底層協議(如UDP)的收發,需要使用者自己定義下層資料包的發送方式,以 callback的方式提供給 KCP, 連時鐘都需要外部傳遞進來,內部不會有任何一次系統呼叫,

整個協議只有 ikcp.h, ikcp.c兩個源檔案,可以方便的集成到用戶自己的協議堆疊中,也許你實作了一個P2P,或者某個基于 UDP的協議,而缺乏一套完善的ARQ可靠協議實作,那么簡單的拷貝這兩個檔案到現有專案中,稍微撰寫兩行代碼,即可使用,

技術特性

TCP是為流量設計的(每秒內可以傳輸多少KB的資料),講究的是充分利用帶寬,而 KCP是為流速設計的(單個資料包從一端發送到一端需要多少時間),以10%-20%帶寬浪費的代價換取了比 TCP快30%-40%的傳輸速度,TCP信道是一條流速很慢,但每秒流量很大的大運河,而KCP是水流湍急的小激流,KCP有正常模式和快速模式兩種,通過以下策略達到提高流速的結果:

RTO翻倍vs不翻倍:

TCP超時計算是RTOx2,這樣連續丟三次包就變成RTOx8了,十分恐怖,而KCP啟動快速模式后不x2,只是x1.5(實驗證明1.5這個值相對比較好),提高了傳輸速度,

選擇性重傳 vs 全部重傳:

TCP丟包時會全部重傳從丟的那個包開始以后的資料,KCP是選擇性重傳,只重傳真正丟失的資料包,

快速重傳:

發送端發送了1,2,3,4,5幾個包,然后收到遠端的ACK: 1, 3, 4, 5,當收到ACK3時,KCP知道2被跳過1次,收到ACK4時,知道2被跳過了2次,此時可以認為2號丟失,不用等超時,直接重傳2號包,大大改善了丟包時的傳輸速度,

延遲ACK vs 非延遲ACK:

TCP為了充分利用帶寬,延遲發送ACK(NODELAY都沒用),這樣超時計算會算出較大 RTT時間,延長了丟包時的判斷程序,KCP的ACK是否延遲發送可以調節,

UNA vs ACK+UNA:

ARQ模型回應有兩種,UNA(此編號前所有包已收到,如TCP)和ACK(該編號包已收到),光用UNA將導致全部重傳,光用ACK則丟失成本太高,以往協議都是二選其一,而 KCP協議中,除去單獨的 ACK包外,所有包都有UNA資訊,

非退讓流控:

KCP正常模式同TCP一樣使用公平退讓法則,即發送視窗大小由:發送快取大小、接收端剩余接收快取大小、丟包退讓及慢啟動這四要素決定,但傳送及時性要求很高的小資料時,可選擇通過配置跳過后兩步,僅用前兩項來控制發送頻率,以犧牲部分公平性及帶寬利用率之代價,換取了開著BT都能流暢傳輸的效果,

快速安裝

您可以使用vcpkg庫管理器下載并安裝kcp:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install kcp

vcpkg中的kcp庫由Microsoft團隊成員和社區貢獻者保持最新狀態,如果版本過時,請在vcpkg存盤庫上創建issue或提出PR,

基本使用

  1. 創建 KCP物件:

    // 初始化 kcp物件,conv為一個表示會話編號的整數,和tcp的 conv一樣,通信雙
    // 方需保證 conv相同,相互的資料包才能夠被認可,user是一個給回呼函式的指標
    ikcpcb *kcp = ikcp_create(conv, user);
  2. 設定回呼函式:

    // KCP的下層協議輸出函式,KCP需要發送資料時會呼叫它
    // buf/len 表示快取和長度
    // user指標為 kcp物件創建時傳入的值,用于區別多個 KCP物件
    int udp_output(const char *buf, int len, ikcpcb *kcp, void *user)
    {
      ....
    }
    // 設定回呼函式
    kcp->output = udp_output;
  3. 回圈呼叫 update:
    // 以一定頻率呼叫 ikcp_update來更新 kcp狀態,并且傳入當前時鐘(毫秒單位)
    // 如 10ms呼叫一次,或用 ikcp_check確定下次呼叫 update的時間不必每次呼叫
    ikcp_update(kcp, millisec);
  4. 輸入一個下層資料包:
    // 收到一個下層資料包(比如UDP包)時需要呼叫:
    ikcp_input(kcp, received_udp_packet, received_udp_size);

    處理了下層協議的輸出/輸入后 KCP協議就可以正常作業了,使用 ikcp_send 來向 遠端發送資料,而另一端使用 ikcp_recv(kcp, ptr, size)來接收資料,

    協議配置

    協議默認模式是一個標準的 ARQ,需要通過配置打開各項加速開關:

      1. 作業模式:

        int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
        • nodelay :是否啟用 nodelay模式,0不啟用;1啟用,
        • interval :協議內部作業的 interval,單位毫秒,比如 10ms或者 20ms
        • resend :快速重傳模式,默認0關閉,可以設定2(2次ACK跨越將會直接重傳)
        • nc :是否關閉流控,默認是0代表不關閉,1代表關閉,
        • 普通模式: ikcp_nodelay(kcp, 0, 40, 0, 0);
        • 極速模式: ikcp_nodelay(kcp, 1, 10, 2, 1);
      2. 最大視窗:
        int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);

        該呼叫將會設定協議的最大發送視窗和最大接收視窗大小,默認為32. 這個可以理解為 TCP的 SND_BUF 和 RCV_BUF,只不過單位不一樣 SND/RCV_BUF 單位是位元組,這個單位是包,

      3. 最大傳輸單元:純演算法協議并不負責探測 MTU,默認 mtu是1400位元組,可以使用ikcp_setmtu來設定該值,該值將會影響資料包歸并及分片時候的最大傳輸單元,
      4. 最小RTO:不管是 TCP還是 KCP計算 RTO時都有最小 RTO的限制,即便計算出來RTO為40ms,由于默認的 RTO是100ms,協議只有在100ms后才能檢測到丟包,快速模式下為30ms,可以手動更改該值:
        kcp->rx_minrto = 10;

        檔案索引

        協議的使用和配置都是很簡單的,大部分情況看完上面的內容基本可以使用了,如果你需要進一步進行精細的控制,比如改變 KCP的記憶體分配器,或者你需要更有效的大規模調度 KCP鏈接(比如 3500個以上),或者如何更好的同 TCP結合,那么可以繼續延伸閱讀:

        • Wiki Home
        • KCP 最佳實踐
        • 同現有TCP服務器集成
        • 傳輸資料加密
        • 應用層流量控制
        • 性能評測

        開源案例

        • kcptun: 基于 kcp-go做的高速遠程埠轉發(隧道) ,配合ssh -D,可以比 shadow.socks 更流暢的看在線視頻,
        • dog-tunnel: GO開發的網路隧道,使用 KCP極大的改進了傳輸速度,并移植了一份 GO版本 KCP
        • v2.ray: 著名代理軟體,Shadow.socks 代替者,1.17后集成了 kcp協議,使用UDP傳輸,無資料包特征,
        • HP-Socket: 高性能網路通信框架 HP-Socket,
        • frp: 高性能內網穿透的反向代理軟體,可將將內網服務暴露映射到外網服務器,
        • asio-kcp: 使用 KCP的完整 UDP網路庫,完整實作了基于 UDP的鏈接狀態管理,會話控制,KCP協議調度等
        • kcp-java: Java版本 KCP協議實作,
        • kcp-netty: kcp的Java語言實作,基于netty,
        • java-kcp: JAVA版本KCP,基于netty實作(包含fec功能)
        • csharp-kcp: csharp版本KCP,基于dotNetty實作(包含fec功能)
        • kcp-cpp: KCP 的多平臺(Windows、MacOS、Linux)C++ 實作作為應用程式中的簡單庫,包含適用于所有平臺的套接字處理和輔助函式,
        • kcp-go: 高安全性的kcp的 GO語言實作,包含 UDP會話管理的簡單實作,可以作為后續開發的基礎庫,
        • kcp-csharp: kcp的 csharp移植,同時包含一份回話管理,可以連接上面kcp-go的服務端,
        • kcp-csharp: 新版本 Kcp的 csharp移植,執行緒安全,運行時無alloc,對gc無壓力,
        • kcp2k: Line-by-line translation to C#, with optional Server/Client on top.
        • kcp-rs: KCP的 rust移植
        • kcp-rust:新版本 KCP的 rust 移植
        • tokio-kcp:rust tokio 的 kcp 集成
        • lua-kcp: KCP的 Lua擴展,用于 Lua服務器
        • node-kcp: node-js 的 KCP 介面
        • nysocks: 基于libuv實作的node-addon,提供nodejs版本的代理服務,客戶端接入支持SOCKS5和ss兩種協議
        • shadow.socks-android: Shadow.socks for android 集成了 kcptun 使用 kcp協議加速 shadow.socks,效果不錯
        • kcpuv: 使用 libuv開發的kcpuv庫,目前還在 Demo階段
        • Lantern:更好的 VPN,Github 50000 星,使用 kcpgo 加速
        • rpcx :RPC 框架,1000+ 星,使用 kcpgo 加速 RPC
        • xkcptun: c語言實作的kcptun,主要用于OpenWrt, LEDE開發的路由器專案上
        • et-frame: C#前后端框架(前端unity3d),統一用C#開發游戲,實作了前后端kcp協議
        • yasio: 一個跨平臺專注于任意客戶端程式的異步socket庫, 易于使用,相同的API操作KCP/TCP/UDP, 性能測驗結果: benchmark-pump.
        • gouxp: 用Go實作基于回呼方式的KCP開發包,包含加解密和FEC支持,簡單易用,

        商業案例

        • 明日帝國:Game K17 的 《明日帝國》 (Google Play),使用 KCP 加速游戲訊息,讓全球玩家流暢聯網
        • 仙靈大作戰:4399 的 MOBA游戲,使用 KCP 優化游戲同步
        • CC:網易 CC 使用 kcp 加速視頻推流,有效提高流暢性
        • BOBO:網易 BOBO 使用 kcp 加速主播推流
        • 云帆加速:使用 KCP 加速檔案傳輸和視頻推流,優化了臺灣主播推流的流暢度
        • SpatialOS: 大型多人分布式游戲服務端引擎,BigWorld 的后繼者,使用 KCP 加速資料傳輸,

        歡迎告知更多案例

        協議比較

        如果網路永遠不卡,那 KCP/TCP 表現類似,但是網路本身就是不可靠的,丟包和抖動無法避免(否則還要各種可靠協議干嘛),在內網這種幾乎理想的環境里直接比較,大家都差不多,但是放到公網上,放到3G/4G網路情況下,或者使用內網丟包模擬,差距就很明顯了,公網在高峰期有平均接近10%的丟包,wifi/3g/4g下更糟糕,這些都會讓傳輸變卡,

        感謝 asio-kcp 的作者 zhangyuan 對 KCP 與 enet, udt做過的一次橫向評測,結論如下:

        • ASIO-KCP has good performace in wifi and phone network(3G, 4G).
        • The kcp is the first choice for realtime pvp game.
        • The lag is less than 1 second when network lag happen. 3 times better than enet when lag happen.
        • The enet is a good choice if your game allow 2 second lag.
        • UDT is a bad idea. It always sink into badly situation of more than serval seconds lag. And the recovery is not expected.
        • enet has the problem of lack of doc. And it has lots of functions that you may intrest.
        • kcp's doc is chinese. Good thing is the function detail which is writen in code is english. And you can use asio_kcp which is a good wrap.
        • The kcp is a simple thing. You will write more code if you want more feature.
        • UDT has a perfect doc. UDT may has more bug than others as I feeling.

        具體見:橫向比較 和 評測資料,為猶豫選擇的人提供了更多指引,

        大型多人游戲服務端引擎 SpatialOS 在集成 KCP 協議后做了同 TCP/RakNet 的評測:

     

     

    對比了在服務端重繪率為 60 Hz 同時維護 50 個角色時的回應時間,詳細對比報告見:

    • Kcp a new low latency secure network stack

    關于協議

    近年來,網路游戲和各類社交網路都在成幾何倍數的增長,不管網路游戲還是各類互動社交網路,互動性和復雜度都在迅速提高,都需要在極短的時間內將資料同時投遞給大量用戶,因此傳輸技術自然變為未來制約發展的一個重要因素,而開源界里各種著名的傳輸協議,如 raknet/enet 之類,一發布都是整套協議堆疊一起發布,這種形式是不利于多樣化的,我的專案只能選擇用或者不用你,很難選擇 “部分用你”,然而你一套協議堆疊設計的再好,是非常難以滿足不同角度的各種需求的,

    因此 KCP 的方式是把協議堆疊 “拆開”,讓大家可以根據專案需求進行靈活的調整和組裝,你可以下面加一層 reed solomon 的糾刪碼做 FEC,上面加一層類 RC4/Salsa20 做流加密,握手處再設計一套非對稱密鑰交換,底層 UDP 傳輸層再做一套動態路由系統,同時探測多條路徑,選最好路徑進行傳輸,這些不同的 “協議單元” 可以像搭建積木一般根據需要自由組合,保證 “簡單性” 和 “可拆分性”,這樣才能靈活適配多變的業務需求,哪個模塊不好,換了就是,

    未來傳輸方面的解決方案必然是根據使用場景深度定制的,因此給大家一個可以自由組合的 “協議單元” ,方便大家集成在自己的協議堆疊中,

    For more information, please see the Success Stories.

    關于作者

    作者:林偉 (skywind3000)

    歡迎關注我的:twitter 和 zhihu,

    我在多年的開發經歷中,一直都喜歡研究解決程式中的一些瓶頸問題,早年喜歡游戲開發,照著《VGA編程》來做游戲圖形,讀 Michael Abrash 的《圖形程式開發人員指南》做軟渲染器,愛好擺弄一些能夠榨干 CPU 能夠運行更快的代碼,參加作業后,興趣轉移到服務端和網路相關的技術,

    2007 年時做了幾個傳統游戲后開始研究快速動作游戲的同步問題,期間寫過不少文章,算是國內比較早研究同步問題的人,然而發現不管怎么解決同步都需要在網路傳輸方面有所突破,后來離開游戲轉行互聯網后也發現不少領域有這方面的需求,于是開始花時間在網路傳輸這個領域上,嘗試基于 UDP 實作一些保守的可靠協議,仿照 BSD Lite 4.4 的代碼實作一些類 TCP 協議,覺得比較有意思,又接著實作一些 P2P 和動態路由網相關的玩具,KCP 協議誕生于 2011 年,基本算是自己傳輸方面做的幾個玩具中的一個,

    Kcptun 的作者 xtaci 是我的大學同學,我倆都是學通信的,經常在一起研究如何進行傳輸優化,

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/kcp.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/404271.html

標籤:其他

上一篇:C/C++ Qt 運用JSON決議庫 [基礎篇]

下一篇:阿里又出神器 !一招定位線上Bug!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more