網絡相關

- -
應用層 Http/Telent/Ftp/Email/DNS
SPDY HTTP2.0繼承
SSL/TLS Secure Sockets Layer
傳輸層 TCP/UDP
網絡層 IP/ICMP/ARP
鏈路層 設備驅動程序及接口

TCP

高可靠性的端到端通信

  1. 基于byte流,每一條TCP連接只能點對點

  2. 全雙工,可以同時進行信號的雙向傳輸

  3. 分組:將應用層數據流打包成若干小數據塊,并封裝在IP分組中(幾百 ~ 40byte)

    • Internet自身無法確保可靠的分組傳輸,超負荷可以隨意丟棄分組,所以TCP實現了自己的確認機制來確保數據的成功傳輸

    • 每個報文段包含一個序列號和數據完整性校驗和,發送后啟動一個定時器;

    • 另一端對收到的數據進行確認,對失序的數據重新排列,丟棄重復數據;并向發送者會送小的確認分組,如果發送者沒有在指定的窗口時間內收到確認信息,發送者就認為分組已被破壞或銷毀,并重新發送數據

報文

三次握手

四次揮手

性能

  1. Nagle算法:將大量的小數據分組綁定在一起,發送全尺寸,提高網絡效率

  2. 延遲確認:由于TCP規定每次都要向發送者回送確認分組,且確認分組報文很小,所以TCP允許在發往相同方向的輸出數據分組中對其進行"捎帶",即將返回的確認信息與輸出的數據分組結合在一起。所以確認分組會在一個特定的時間窗口(100 ~ 200 ms)內將輸出確認放在緩沖區,以尋找能夠捎帶的輸出數據分組。如果沒有等到,則放在單獨的分組中傳輸

  3. TCP慢啟動:為了防止網絡突然過載和擁塞,限制了TCP端口在任意時刻可以傳輸的分組數。每成功接收一個分組,就可以發送兩個分組,等待確認后,可以發送四個分組,一次類推。表現為某個HTTP事務有大量數據要發送,是不能一次將所有分組都發送出去的;新連接的傳輸速度會比已經交換過一定數量的連接慢一些

  4. TIME_WAIT:當某個TCP端點關閉連接時,會在內存中維護一個小的控制塊,用來記錄最近關閉連接的IP地址和端口號。這類信息指揮維持一小段時間,以防止創建、關閉并重新創建兩個具備相同IP、端口號的連接;但在高并發情況下可能引起端口耗盡問題,要解決這個問題可以使用負載均衡(增加機器數量)

HTTP

建立在TCP協議之上,所以瓶頸及其優化技巧都是基于TCP協議本身的特性

年份 版本 改動內容
1991 0.9 只有GET方式
1996 1.0 GET、POST、HEAD方式,加入Header
*1997 1.1 多種提交方式,默認都是持續連接
2009 SPDY
2015 2.0

Request

GET /index.html HTTP/1.1
Accept: mime type
Accept-Encoding:
If-Modified-Since: EEE, dd MMM yyyy HH:mm:ss z  // 文件是否修改
Referer: http://www.it315.org/index.jsp         // 說明請求來自哪里,防盜鏈
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) 客戶端代理
Cookie                                          // 向服務器發送Cookie
Range: byte=100-999                             //  多線程多點續傳

username=ccy&userpwd=118

Response

Content-Type: mime type; charset=utf-8
Content-Encoding: gzip
statusCode reasonPhrase
204 返回內容為空httpResponse.getEntity() == null
302 重定向
304 未修改,沒有消息體;header信息可能不完成,需要和緩存合并
404 Not Found
409 資源沖突

長短鏈接

短連接

HTTP的主要缺點是,每個TCP連接只能發送一個請求,發送完畢后就關閉;keep-alive確保服務器將保持這個tcp連接一段時間直到會話保持的時間超過keepaliveTime時,client和server端將主動釋放tcp連接

  1. 降低三次握手時延
  2. 減少打開鏈接的數量
  3. 避免慢啟動
  1. HTTP/1.0需要主動聲明Connection: keep-aliveHTTP1.1默認都是
  2. 如果服務器提供的是一個接口服務(除了動態內容,幾乎沒有引用任何靜態內容)不建議開啟;如果服務器提供的是Web站點服務(一個頁面除了動態內容,還包含非常多的JS、圖片、css文件等)建議開啟(打開1個網頁會建立10~50個TCP連接)

長連接(推送)

客戶端和服務端之間始終建立著一個通信連接,在連接沒有中斷之前,可以隨時進行通信

  1. 斷開重連、心跳檢測
  2. 可以通過HTTP輪詢的方式實現偽長連接。(頻繁握手、協議冗余)

緩存

參見 HttpHeaderParser.parseCacheHeaders

Cache.Entry Req Header 說明
ttl Cache-Control no-cache/no-store、max-age(stale-while-revalidate/must-revalidate/proxy-revalidate)
serverDate Date 服務器時間
ttl Expires 在該時間后被認為失效,可以和Date配合計算出存活時間
lastModified Last-Modified 文件最后修改時間
etag ETag 根據特殊算法計算的一串字符,通過對比字符判斷是否修改過
  • Cache-Control設置的內容優先級較高會覆蓋其他設置

文件上傳

  • application/x-www-form-urlencoded 在發送前默認編碼所有字符
  • multipart/form-data 不對字符編碼,瀏覽器對上傳實體內容中的每個字段用分割線進行分割,兩個分割線間的內容成為一個分區,每個分區包含兩個部分,一部分是對表單字段元素進行描述,另外一部分是表單字段元素的主體內容
<form method="post" enctype="multipart/form-data">
    <input type="file"/>
</from>

Content-Type:multipart/form-data; boundary=--------------------------7dc2af520870

--------------------------7dc2af520870


  • 服務端要獲得上傳的文件,需要用request.getHeader("Content-Type")來取得實體內容的分界字符串,通過request.getInputStream()得到上傳的整個post實體流,然后根據HTTP協議,把文件部分給篩選出來,保存在服務端磁盤中;其他表單值不能直接使用request.getParamter()獲得

HTTPS

OpenSSL是一個強大的安全套接字層密碼庫,囊括主要的密碼算法、常用的密鑰和證書封裝管理功能及SSL協議

客戶端 服務端
發送SSL/TLS信息、算法信息 + 隨機數RNC(Random Number Client) -
- 回復SSL/TLS信息、算法信息、證書 + 隨機數RNS(Random Number Server)
驗證證書;產生新的隨機數PMS(Pre-Master Secret),使用【三個隨機數】構建主密鑰MS,并用證書里的公鑰向加密PMS發送給服務端 -
- 通過私鑰獲得PMS,同樣使用【三個隨機數】構建主密鑰MS

至此握手階段結束,接下來使用普通的HTTP協議,只不過使用會話密鑰加密內容

HTTP2.0 & SPDY

  • 頭信息壓縮機制 :Header壓縮后發送,同時客戶端和服務端同時維護一張頭信息,所有字段都生成一個索引號,以后就只發送索引號

  • 多路復用/管道化鏈接:針對HTTP高延遲的問題,通過多個請求stream共享一個tcp連接的方式,降低延遲同時提高帶寬的利用率

  • 請求優先級:允許給每個request設置優先級,重要的請求會優先得到響應

  • 服務端推送

  • 基于HTTPS的加密協議傳輸

API

HttpUrlConnection

HttpURLConnection conn = null;
try {
    conn = (HttpURLConnection) new URL(encodeURL).openConnection();
    conn.setConnectTimeout(timeoutMs);
    conn.setReadTimeout(timeoutMs);
    conn.setUseCaches(false);
    conn.setDoOutput(true); // conn.setRequestMethod("POST");
    conn.setRequestProperty("If-Modified-Since", "");

    int nRC = conn.getResponseCode(); // 觸發getInputStream(connect()); connected = true;
    if (nRC == HttpURLConnection.HTTP_OK) {
        conn.getInputStream();
    } else if (nRC == 304) {
    }
} finally {
    conn.disconnect();  // input/outputStream closed
}

AsyncHttpClient

Volley

OKHttp

OkHttpClient httpClient = new OkHttpClient();

Request request = new Request.Builder()
                    .url("http://www.baidu.com/")
                    .build();

Call call = httpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Request request, IOException e) {
        mTvConten.setText(request.toString());
    }

    @Override
    public void onResponse(Response response) throws IOException {
        String htmlStr = response.body().string();
        mTvConten.setText(htmlStr);

    }
});

Retrofit

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .client(client) // 自定義client
        .build();

// 定義連網接口
GitHubService service = retrofit.create(GitHubService.class);
// Call 模式
Call<User> repos = service.getUserByName("CatDog118");
// Rxjava 模式
Observable<User> getUserByName(@Path("user") String user);

// execute同步請求; enqueue異步請求
repos.enqueue(new Callback<User>() {
    public void onResponse(Call<User> call, Response<User> response) {}
    public void onFailure(Call<User> call, Throwable t) {}
});

// 取消請求
call.cancel();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容