1. 程式人生 > >走入計算機的第三十四天(基於tcp和udp的套接字)

走入計算機的第三十四天(基於tcp和udp的套接字)

recv 設置 內存 tcp list dup lis 不知道 狀態

一 TCP套接字

1 low版TCP套接字

服務器端                              客戶端

    技術分享技術分享

  2、改進版tcp套接字

          服務端                        客戶端

   技術分享技術分享

二、UDP的套接字

        服務器                        客戶端

  技術分享技術分享

    註:udp的套接字可以支持多個客戶端同時訪問,但tcp套接字就不行了,那是因為tcp套接字有tcp三次握手四次揮手。

三、recv和recvfrom的區別?

  1、提前須知:

    1.1tcp是send發送消息,recv接收消息。

    1.2udp是sendto發送消息,recvfrom接收消息。

    1.3 在我眼裏看來send只是發送一個數據對象,所以recv接收的也只是一個數據對象,而sendto發送的是個數據對象和ip端口兩個信   息,所以接收的也應該是個數據對象和ip端口信息。

  2、tcp是基於數據流工作的,而udp是基於數據報工作的。

    2.1send(bytes_data)發送數據流時當數據流的數據為空那麽發送到自己的socket緩存區時,操作系統會把空包發過去。

    2.2sendto(bytes_data,ip_port):發送數據報時,數據報中的數據為空但是ip和端口是不會為空的,發送到自己的緩存區後操作系統就會  對該數據進行處理

  3、recv和recvfrom

    3.1在tcp協議中如果服務器端接收緩沖區的數據為空,那麽recv就會處於阻塞或者等待狀態,這樣客戶端就一直沒有返回的結果了。

    3.2tcp協議基於鏈接通信:

       基於鏈接通信就必須指定半連接池的大小——listen()

       基於鏈接必須先運行服務器端服務然後再運行客戶端服務

       基於鏈接如果一端斷開那麽另一端也會跟著斷開,所以要麽在服務器端異常處理,要麽設置if判斷

    3.3在udp協議中如果服務器端接收緩沖區的數據為空,那麽recvfrom也會阻塞,但是只不過dup協議的客戶端sendto一個空數據並不是真的空數據,還有地址信息,所以服務器端也可以recvfrom到數據。

    3.4udp協議是無連接通信:

        所以不需要指定什麽連接池的,也不需要服務器端運行了才能發送數據

三、粘包

  1、粘包須知:只有tcp協議才會出現粘包,udp協議是不會粘包的。

  2、什麽是粘包?

    2.1如圖所示:

      技術分享

    2.2無論是在服務端還是在客戶端程序都是存在於用戶態的,程序要想接受或者是發送數據都必須把數據交給操作系統,由操作系統來  控制底層硬件,從而達到發送數據和接受數據。而把數據是怎麽交到操作系統手裏的呢,首先程序會把數據發送到他的緩存空間裏面,默認  大小是8K,然後操作系統來讀取他的這個緩存空間中的數據從而進行轉發。讀分為兩種情況,當緩存中的內存在規定的時間內占滿了那麽操  作系統就會讀取緩存中的內容,還有一種情況就是當緩存中的數據超過規定的時間那麽操作系統也會讀取緩存中的數據進行轉發。

    2.3無論是服務端還是客戶端的發送或者是接收的大小都可以自己定義,因為對於tcp協議的應用程序來說他們看到的只是個整體或者說  是個流,一條消息有多少個自己他們是看不到的,所以說tcp協議是面向於流的協議,所以在接收一個數據時tcp不知道該數據到底要接收多  少個字節,然後就出現了粘包現象。

    2.4tcp協議是面向消息的協議,每一個udp段都是一段數據,或者說是一段消息,應用程序必須以這段消息為單位來提取這段數據,不  能一次性提取任意字節的數據,這一點和tcp協議很不相同,所以說udp協議是不會出現粘包現象的。

    2.5因此在tcp協議中所謂的粘包現象無非就是好接收者不知道到底該接收多少個字節的數據而已。

  3、小結:

    3.1:udp協議的recvfrom()是阻塞的,一個recvfrom(x)必須對一個sendto(y)收完了才算完成傳輸,如果x>y就會出現丟包現象。

    3.2:tcp協議數據不會丟失沒有收完包,下次連接會基於上次連接再進行傳輸。傳輸端接收到ack時才會清空緩沖區的內容。

  4、兩種清空下產生粘包現象

    4.1::當發送者的緩存區在規定的時間內滿了後發送數據會產生粘包現象。

    4.2:客戶端在規定的時間內在緩沖區沒有完全的接收到發送者發來的包,只接受到了一部分包,那麽下一次接收時就會產生粘包現  象。

  5、應當註意的一些問題。

    5.1當發送到發送的數據包大於網卡規定MTU的大小時,這時網卡會把該數據包分成幾個小數據包發送出去,只要接收端依次接收就可  以了。  

    5.2send的字節流先發送到自己的緩存區(該緩存區可能還緩存的有其他數據),那麽當需要緩存的數據大小大於剩余緩存區的空間這樣就會數據丟失,所以用sendall就會循環發送需要緩存的數據,解決了數據丟失問題。

走入計算機的第三十四天(基於tcp和udp的套接字)