天天看點

python網絡程式設計難點_Python網絡程式設計tcp詳解(基礎篇十四)

網絡程式設計tcp

1 TCP詳解

<1> tcp概述

TCP:英文全拼(Transmission Control Protocol)簡稱傳輸控制協定,它是一種面向連接配接的、可靠的、基于位元組流的傳輸層通信協定.

TCP通信需要經過建立連接配接、資料傳送、終止連接配接三個步驟。

TCP通信模型中,在通信開始之前,一定要先建立相關的連結,才能發送資料,類似于生活中,"打電話""

<2> tcp特點

面向連接配接:通信雙方必須先建立連接配接才能進行資料的傳輸,雙方都必須為該連接配接配置設定必要的系統核心資源,以管理連接配接的狀态和連接配接上的傳輸。

雙方間的資料傳輸都可以通過這一個連接配接進行。

完成資料交換後,雙方必須斷開此連接配接,以釋放系統資源。

這種連接配接是一對一的,是以TCP不适用于廣播的應用程式,基于廣播的應用程式請使用UDP協定。

可靠傳輸:TCP采用發送應答機制

TCP發送的每個封包段都必須得到接收方的應答才認為這個TCP封包段傳輸成功

逾時重傳

發送端發出一個封包段之後就啟動定時器,如果在定時時間内沒有收到應答就重新發送這個封包段。

TCP為了保證不發生丢包,就給每個包一個序号,同時序号也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的确認(ACK);如果發送端實體在合理的往返時延(RTT)内未收到确認,那麼對應的資料包就被假設為已丢失将會被進行重傳。

錯誤校驗

由發送端計算,然後由接收端驗證,其目的是為了檢測資料在發送端到接收端之間是否有改動,如果接收方檢測到校驗和有差錯,則直接丢棄這個資料包。

流量控制和阻塞管理

流量控制用來避免主機發送得過快而使接收方來不及完全收下。

<3> tcp優缺點優點:可靠,穩定

适合傳輸大量資料缺點:傳輸速度慢

占用系統資源高

2 tcp用戶端

所謂的用戶端,就是需要被服務的一方,而伺服器端就是提供服務的一方.

示例代碼:

import socket

# 建立tcp socket

tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 目的資訊

server_ip = input("請輸入伺服器ip:")

server_port = int(input("請輸入伺服器port:"))

# 連結伺服器

tcp_client_socket.connect((server_ip, server_port))

# 提示使用者輸入資料

send_data = input("請輸入要發送的資料:")

tcp_client_socket.send(send_data.encode("gbk"))

# 接收對方發送過來的資料,最大接收1024個位元組

recvData = tcp_client_socket.recv(1024)

print('接收到的資料為:', recvData.decode('gbk'))

# 關閉套接字

tcp_client_socket.close()

運作結果:

TCP 用戶端:

請輸入伺服器ip:10.10.0.47

請輸入伺服器port:8080

請輸入要發送的資料:你好啊

接收到的資料為: 我很好,你呢

網絡調試助手:

小結connect 用于和伺服器程式建立連接配接

send 方法用于 TCP 套接字發送資料

recv 方法用于 TCP 套接字接收資料

3 tcp服務端

想要完成一個tcp伺服器的功能,需要的流程如下:socket建立一個套接字

bind綁定ip和port

listen使套接字變為可以被動連結

accept等待用戶端的連結

recv/send接收發送資料

一個很簡單的tcp伺服器如下:

import socket

# 建立socket

tcp_server_socket = socket(socket.AF_INET, socket.SOCK_STREAM)

# 本地資訊

address = ('', 7788)

# 綁定

tcp_server_socket.bind(address)

# 設定監聽

# 使用socket建立的套接字預設的屬性是主動的,使用listen将其變為被動的,這樣就可以接收别人的連結了

# 128:表示最大等待連接配接數

tcp_server_socket.listen(128)

# 如果有新的用戶端來連結伺服器,那麼就産生一個新的套接字專門為這個用戶端服務

# client_socket用來為這個用戶端服務

# tcp_server_socket就可以省下來專門等待其他新用戶端的連結

client_socket, clientAddr = tcp_server_socket.accept()

# 接收對方發送過來的資料

recv_data = client_socket.recv(1024) # 接收1024個位元組

print('接收到的資料為:', recv_data.decode('gbk'))

# 發送一些資料到用戶端

client_socket.send("thank you !".encode('gbk'))

# 關閉為這個用戶端服務的套接字,隻要關閉了,就意味着為不能再為這個用戶端服務了,如果還需要服務,隻能再次重新連接配接

client_socket.close()

運作結果:

TCP服務端

接收到的資料為: 你在麼?

網絡調試助手:

小結listen 方法用于把伺服器套接字設定為監聽模式

accept 方法用于等待接收用戶端的連接配接請求

4 tcp網絡程式設計注意點TCP 伺服器一般情況下都需要綁定端口号,否則用戶端找不到這個伺服器

TCP 用戶端一般不綁定端口号,使用随機生成的端口号即可

TCP 伺服器中通過 listen 可以将 socket 建立出來的主動套接字變為被動的,這是做 TCP 伺服器時必須要做的

當 TCP 用戶端和服務端建立好連接配接才可以收發資料,UDP 是不需要建立連接配接,直接就可以發送資料

當一個 TCP 用戶端和服務端連接配接成功後,伺服器端會有1個新的套接字,這個套接字用來标記這個用戶端,單獨為這個用戶端服務

listen 後的套接字是被動套接字,用來接收新的用戶端的連結請求的,而accept傳回的新套接字是标記這個新用戶端的

關閉 listen 後的套接字意味着被動套接字關閉了,會導緻新的用戶端不能夠連結伺服器,但是之前已經連結成功的用戶端正常通信。

關閉 accept 傳回的套接字意味着這個用戶端已經服務完畢

當用戶端的套接字調用 close 後,伺服器端會 recv 解堵塞,并且傳回的長度為0,是以伺服器可以通過傳回資料的長度來差別用戶端是否已經下線