1. 程式人生 > 實用技巧 >pytorch讀取一張影象進行分類預測需要注意的問題(opencv、PIL)

pytorch讀取一張影象進行分類預測需要注意的問題(opencv、PIL)

socket 程式設計

主要是轉載和記錄。

tcp程式設計

傳輸控制協議(TCP,Transmission Control Protocol)是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議,由IETF的 RFC793 定義

  • 面向連線

    為了保證可靠性,雙方在通訊前要進行3次握手來建立連線,之後才通訊,故廣播和多播不會承載在tcp上。

  • 可靠性

    由於TCP處於多跳通訊的IP層之上,而IP層並不提供可靠的傳輸,因此在TCP層看來就有四種常見傳輸錯誤問題,分別是位元錯誤(packet bit errors)、包亂序(packet reordering)、包重複(packet duplication)、丟包(packet erasure或稱為packet drops),TCP要提供可靠的傳輸,就需要有額外的機制處理這幾種錯誤。

    因此個人理解可靠性體現在三個方面,首先TCP通過超時重傳和快速重傳兩個常見手段來保證資料包的正確傳輸,也就是說接收端在沒有收到資料包或者收到錯誤的資料包的時候會觸發傳送端的資料包重傳(處理位元錯誤和丟包)。其次TCP接收端會快取接收到的亂序到達資料,重排序後在嚮應用層提供有序的資料(處理包亂序)。最後TCP傳送端會維持一個傳送"視窗"動態的調整發送速率以適用接收端快取限制和網路擁塞情況,避免了網路擁塞或者接收端快取滿而大量丟包的問題(降低丟包率)。因此可靠性需要TCP協議具有超時與重傳管理、視窗管理、流量控制、擁塞控制等功能。

  • 位元組流

    應用層傳送的資料會在TCP的傳送端快取起來,統一分片(例如一個應用層的資料包分成兩個TCP包)或者打包(例如兩個或者多個應用層的資料包打包成一個TCP資料包)傳送,到接收端的時候接收端也是直接按照位元組流將資料傳遞給應用層。作為對比,同樣是傳輸層的協議,UDP並不會對應用層的資料包進行打包和分片的操作,一般一個應用層的資料包就對應一個UDP包。這個也是伴隨TCP視窗管理、擁塞控制等。

tcp報文格式

 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
|            Source Port            |          Destination Port         |
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
|                            Sequence Number                            |
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
|                         Acknowledgment Number                         |
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
| Data  |               |U|A|P|R|S|F|                                   |
|Offset |   Reserved    |R|C|S|S|Y|I|               Window              |
|       |               |G|K|H|T|N|N|                                   |
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
|              Checksum             |           Urgent Pointer          |
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
|                     Options                         |     Padding     |
+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+
  • 源埠(Source Port)和目的埠(Destination Port)

  • 序列號(Sequence Number)

    tcp傳輸可靠性的基礎,每一幀傳送的資料每一個位元組都有一個對應的序列號,而tcp首部的序列號代表第一個位元組的序列號,那麼這一幀資料最後一個位元組的序列號是tcp首部的序列號+資料位元組長度。

  • 確認序列號(Acknowledgment Number)

    告訴傳送端這個序號之前的資料都已經正確接收到了。該欄位只有標誌位中ACK為1時才有效。注意是之前,也就是填寫的應是接收到的最後一個位元組的序列號+1。

  • 資料偏移/首部長度(Data Offset/Header Length)

    4個位元組,tcp首部不是固定的,除了前20位元組外還有個長度可變的選項,這個代表的不是多少個byte,而是多少個word,4位元組最大的16,所以tcp首部最大是64byte。

  • 預留(Reserved)

  • 標誌位(Flag)

    1. URG: 為1時緊急指標有效
    2. ACK: 為1時確認序列號有效
    3. PSH: PUSH標誌,為1時接收端接收到後應儘快交給應用層,而不是在緩衝區排隊
    4. RST: 為1時表示重連,重置錯誤的連線或者拒絕非法的請求連線
    5. SYN: 同步序號,主要用於tcp三次握手連線的時候發起一個新連線
    6. FIN: Finnish標誌,主要用於tcp四次揮手斷開連線的時候
  • 滑動視窗(Window)

    用於接收端告訴傳送端我這邊接收的快取大小,從而控制傳送速率,達到流量控制,佔位是16bit,所以最大是65535。

  • 校驗和(Checksum)

  • 緊急指標(Urgent Pointer)

    用於tcp傳送緊急資料,是一個正的偏移量,和序列號相加得到的數就是最後一個緊急資料的序列號。

  • 選項和填充(Options and Padding)

tcp三次握手,四次揮手

  • 三次握手

  1. client 發起連線,要填充正確的代表建立連線資訊的tcp首部,這隻需要把標誌位SYN置位1,
    填寫起始序列號x(一般為1),傳送之後client端進入了 SYN-SEND 狀態。

  2. server 接收到請求後要做兩個動作,一是告訴client我已經接收到你的請求,同意建立連線,
    二是要發起server到client的連線申請,tcp連線是雙向的。然後server進入了 SYN-RCVD 狀態。
    根據上面tcp報文的分析,對於一,要把確認序列號填寫為x+1,標誌ACK置位為1。
    對於二,則和上面一樣,填寫起始序列號y,標誌SYN置位1。

  3. client 接收到後也是兩個動作,一是檢驗資料看伺服器是否接收請求,即確認序列號是否為x+1,
    二是迴響應,表示接收到server的請求,此時確認序列號填y+1,標誌位ACK置位1。而序列號也正常遞增
    為x+1,之後client進入 ESTATLISHED 狀態。

  • 四次揮手

  1. client 傳送斷開連線的申請,然後進入終止等待1狀態(FIN-WAIT-1),此後不再發送應用層的資料。

    client斷開連線報文內容應是:標誌FIN=1,序列seq=u。

  2. server 接收到client的釋放連線請求後,返回一個響應。然後進入了關閉等待狀態(CLOSE-WAIT)。
    client收到了server的響應清楚了server已經接收到了,隨後進入了終止等待2狀態(FIN-WAIT-2)。此時
    client端到server端連線釋放完畢。

    響應報文內容應是:標誌ACK=1,確認序列ack=u+1,序列seq=v。

  3. 和3次握手不一樣的是,server並沒有把關閉server到client的連線鏈路和步驟2合併在一起,原因是server
    可能仍然有資料沒有傳送完,所以server在 CLOSE-WAIT 狀態要完成剩餘資料的傳送。然後在想client傳送斷開
    報文。server隨後進入最後確認狀態(LAST-ACK),此後也不在發資料給client。

    server斷開連線報文內容應是:標誌FIN=1,序列seq=w。

    不僅如此,仍設定標誌ACK=1,確認序列ack=u+1。(可能是為了讓client確認是與上兩個步驟是對應的?)

  4. client收到server釋放連線的請求後,迴響應告知server已經收到,並進入 TIME-WAIT 狀態等待2MSL。
    server接收到響應後進入CLOSED狀態,此時server端到client端連線釋放完畢。而client端等待2MSL後也進入CLOSED狀態。

    響應報文內容應是:標誌ACK=1,確認序列ack=w+1。

    這裡還設定序列seq=u+1(不清楚為什麼)

  • 相關問題
  1. 為什麼是3次握手,而揮手是4次

    握手連線因為server可以把client申請連線的應答報文和自己向client申請連線的報文合併為一條,而揮手不行,因為server端可能有未傳送完成的資料,不能馬上關閉server到client的鏈路。

  2. TIME_WAIT 狀態是什麼,為什麼要等2MSL

    設定這個狀態的目的是保證最後一個應答server端能夠正確接收到,因為網路 的不穩定性,最後一個應答可能會丟失。Server如果沒有收到ACK,將不斷重複傳送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在傳送出ACK之後進入到TIME_WAIT狀態。Client會設定一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網路中最大的存活時間,2MSL就是一個傳送和一個回覆所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP連線。

reference