Python?socket之TCP通信及下載文件的實(shí)現(xiàn)
TCP簡介
TCP介紹
TCP協(xié)議,傳輸控制協(xié)議(英語:Transmission Control Protocol,縮寫為 TCP)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,由IETF的RFC 793定義。
TCP通信需要經(jīng)過創(chuàng)建連接、數(shù)據(jù)傳送、終止連接三個(gè)步驟。
TCP通信模型中,在通信開始之前,一定要先建立相關(guān)的鏈接,才能發(fā)送數(shù)據(jù),類似于生活中,“打電話”
TCP特點(diǎn)
1. 面向連接
通信雙方必須先建立連接才能進(jìn)行數(shù)據(jù)的傳輸,雙方都必須為該連接分配必要的系統(tǒng)內(nèi)核資源,以管理連接的狀態(tài)和連接上的傳輸。
雙方間的數(shù)據(jù)傳輸都可以通過這一個(gè)連接進(jìn)行。
完成數(shù)據(jù)交換后,雙方必須斷開此連接,以釋放系統(tǒng)資源。
這種連接是一對一的,因此TCP不適用于廣播的應(yīng)用程序,基于廣播的應(yīng)用程序請使用UDP協(xié)議。
2. 可靠傳輸
1)TCP采用發(fā)送應(yīng)答機(jī)制
TCP發(fā)送的每個(gè)報(bào)文段都必須得到接收方的應(yīng)答才認(rèn)為這個(gè)TCP報(bào)文段傳輸成功
2)超時(shí)重傳
發(fā)送端發(fā)出一個(gè)報(bào)文段之后就啟動(dòng)定時(shí)器,如果在定時(shí)時(shí)間內(nèi)沒有收到應(yīng)答就重新發(fā)送這個(gè)報(bào)文段。
TCP為了保證不發(fā)生丟包,就給每個(gè)包一個(gè)序號(hào),同時(shí)序號(hào)也保證了傳送到接收端實(shí)體的包的按序接收。然后接收端實(shí)體對已成功收到的包發(fā)回一個(gè)相應(yīng)的確認(rèn)(ACK);如果發(fā)送端實(shí)體在合理的往返時(shí)延(RTT)內(nèi)未收到確認(rèn),那么對應(yīng)的數(shù)據(jù)包就被假設(shè)為已丟失將會(huì)被進(jìn)行重傳。
3)錯(cuò)誤校驗(yàn)
TCP用一個(gè)校驗(yàn)和函數(shù)來檢驗(yàn)數(shù)據(jù)是否有錯(cuò)誤;在發(fā)送和接收時(shí)都要計(jì)算校驗(yàn)和。
4) 流量控制和阻塞管理
流量控制用來避免主機(jī)發(fā)送得過快而使接收方來不及完全收下。
TCP與UDP的不同點(diǎn)
TCP | UDP | |
1 | TCP的傳輸是可靠傳輸。 | UDP的傳輸是不可靠傳輸。 |
2 | TCP是基于連接的協(xié)議,在正式收發(fā)數(shù)據(jù)前,必須和對方建立可靠的連接。 | UDP是和TCP相對應(yīng)的協(xié)議,它是面向非連接的協(xié)議,它不與對方建立連接,而是直接把數(shù)據(jù)包發(fā)送出去 |
3 | TCP是一種可靠的通信服務(wù),負(fù)載相對而言比較大,TCP采用套接字(socket)或者端口(port)來建立通信。 | UDP是一種不可靠的網(wǎng)絡(luò)服務(wù),負(fù)載比較小。 |
4 | TCP和UDP結(jié)構(gòu)不同,TCP包括序號(hào)、確認(rèn)信號(hào)、數(shù)據(jù)偏移、控制標(biāo)志(通常說的URG、ACK、PSH、RST、SYN、FIN)、窗口、校驗(yàn)和、緊急指針、選項(xiàng)等信息。 | UDP包含長度和校驗(yàn)和信息。 |
5 | TCP提供超時(shí)重發(fā),丟棄重復(fù)數(shù)據(jù),檢驗(yàn)數(shù)據(jù),流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端。 | UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報(bào)發(fā)送出去,但是并不能保證它們能到達(dá)目的地。 |
6 | TCP在發(fā)送數(shù)據(jù)包前在通信雙方有一個(gè)三次握手機(jī)制,確保雙方準(zhǔn)備好,在傳輸數(shù)據(jù)包期間,TCP會(huì)根據(jù)鏈路中數(shù)據(jù)流量的大小來調(diào)節(jié)傳送的速率,傳輸時(shí)如果發(fā)現(xiàn)有丟包,會(huì)有嚴(yán)格的重傳機(jī)制,故而傳輸速度很慢。 | UDP在傳輸數(shù)據(jù)報(bào)前不用在客戶和服務(wù)器之間建立一個(gè)連接,且沒有超時(shí)重發(fā)等機(jī)制,故而傳輸速度很快。 |
7 | TCP支持全雙工和并發(fā)的TCP連接,提供確認(rèn)、重傳與擁塞控制。 | UDP適用于哪些系統(tǒng)對性能的要求高于數(shù)據(jù)完整性的要求,需要“簡短快捷”的數(shù)據(jù)交換、需要多播和廣播的應(yīng)用環(huán)境。 |
tcp通信模型
udp通信模型中,在通信開始之前,不需要建立相關(guān)的鏈接,只需要發(fā)送數(shù)據(jù)即可,類似于生活中,“寫信”
tcp通信模型中,在通信開始之前,一定要先建立相關(guān)的鏈接,才能發(fā)送數(shù)據(jù),類似于生活中,“打電話”


tcp注意點(diǎn)
- tcp服務(wù)器一般情況下都需要綁定,否則客戶端找不到這個(gè)服務(wù)器
- tcp客戶端一般不綁定,因?yàn)槭侵鲃?dòng)鏈接服務(wù)器,所以只要確定好服務(wù)器的ip、port等信息就好,本地客戶端可以隨機(jī)
- tcp服務(wù)器中通過listen可以將socket創(chuàng)建出來的主動(dòng)套接字變?yōu)楸粍?dòng)的,這是做tcp服務(wù)器時(shí)必須要做的
- 當(dāng)客戶端需要鏈接服務(wù)器時(shí),就需要使用connect進(jìn)行鏈接,udp是不需要鏈接的而是直接發(fā)送,但是tcp必須先鏈接,只有鏈接成功才能通信
- 當(dāng)一個(gè)tcp客戶端連接服務(wù)器時(shí),服務(wù)器端會(huì)有1個(gè)新的套接字,這個(gè)套接字用來標(biāo)記這個(gè)客戶端,單獨(dú)為這個(gè)客戶端服務(wù)
- listen后的套接字是被動(dòng)套接字,用來接收新的客戶端的鏈接請求的,而accept返回的新套接字是標(biāo)記這個(gè)新客戶端的
- 關(guān)閉listen后的套接字意味著被動(dòng)套接字關(guān)閉了,會(huì)導(dǎo)致新的客戶端不能夠鏈接服務(wù)器,但是之前已經(jīng)鏈接成功的客戶端正常通信,因?yàn)閍ccept返回了新的套接字。
- 關(guān)閉accept返回的套接字意味著這個(gè)客戶端已經(jīng)服務(wù)完畢
- 當(dāng)客戶端的套接字調(diào)用close后,服務(wù)器端會(huì)recv解堵塞,并且返回的長度為0,就是recv()返回為空, sendto不能發(fā)送空消息,因此服務(wù)器可以通過返回?cái)?shù)據(jù)的長度來區(qū)別客戶端是否已經(jīng)下線
代碼:
TCPServer:
import socket
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("0.0.0.0", 8080))
# 將套接字將默認(rèn)的主動(dòng)模式改成被動(dòng)模式(監(jiān)聽模式)
tcp_server.listen(128)
ret = tcp_server.accept()
print(ret)
tcp_server.close()TCPClient:
import socket
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(("192.168.1.12", 8080))
tcp_client.send("hello,world!!!".encode("utf-8"))
tcp_client.close()運(yùn)行結(jié)果:

TCP服務(wù)端與客戶端消息通信:
代碼:
TCPServer:
import socket
import threading
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("", 8080))
# 將套接字將默認(rèn)的主動(dòng)模式改成被動(dòng)模式(監(jiān)聽模式)
tcp_server.listen(128)
client_socket, client_info = tcp_server.accept()
def deal_msg():
while True:
data = client_socket.recv(1024)
print(data)
# 當(dāng)客戶端關(guān)閉了連接,服務(wù)端的連接套接字也會(huì)繼續(xù)執(zhí)行接收函數(shù),但返回的是空字符串,這時(shí)服務(wù)端的連接套接字就可以關(guān)閉了
if data == "":
break
client_socket.close()
threading.Thread(target=deal_msg).start()
print(client_socket, client_info)
tcp_server.close()TCPClient:
import socket
import time
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(("192.168.1.12", 8080))
while True:
time.sleep(2)
tcp_client.send("hello,world!!!".encode("utf-8"))
# tcp_client.close()下載文件:
TCPDownloaderServer:
import socket
import threading
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("0.0.0.0", 8080))
tcp_server.listen(128)
tcp_client, clint_info = tcp_server.accept()
def send_file():
with open("./test.txt", "rb") as fp:
while True:
byteData = fp.read(128)
print(byteData)
if byteData:
tcp_client.send(byteData)
else:
break
tcp_client.close()
threading.Thread(target=send_file).start()
tcp_server.close()TCPDownloaderClient:
import socket
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(("192.168.1.12", 8080))
with open("./test2.txt", "wb") as fp:
while True:
data = tcp_client.recv(1024)
print(data)
if data.decode("utf-8") == "":
break
fp.write(data)
tcp_client.close()到此這篇關(guān)于Python socket之TCP通信及下載文件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python TCP通信下載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)簡單socket程序在兩臺(tái)電腦之間傳輸消息的方法
這篇文章主要介紹了python實(shí)現(xiàn)簡單socket程序在兩臺(tái)電腦之間傳輸消息的方法,涉及Python操作socket的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
Python機(jī)器學(xué)習(xí)之AdaBoost算法
今天帶大家來學(xué)習(xí)Python機(jī)器學(xué)習(xí),文中對AdaBoost算法介紹的很詳細(xì),有非常多的代碼示例,對正在學(xué)習(xí)python的小伙伴們有很好地幫助,需要的朋友可以參考下2021-05-05
Python列表之間的數(shù)字與字符轉(zhuǎn)化實(shí)例
在python列表操作中,面對需要把列表中的字符串轉(zhuǎn)為禮拜的操作,無需強(qiáng)轉(zhuǎn),通過簡單的幾步就可以實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Python列表之間的數(shù)字與字符轉(zhuǎn)化的相關(guān)資料,需要的朋友可以參考下2023-02-02
python利用paramiko實(shí)現(xiàn)交換機(jī)巡檢的示例
這篇文章主要介紹了python利用paramiko實(shí)現(xiàn)交換機(jī)巡檢,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09
詳解Python圖像形態(tài)學(xué)處理(開運(yùn)算,閉運(yùn)算,梯度運(yùn)算)
數(shù)學(xué)形態(tài)學(xué)(Mathematical Morphology)是一種應(yīng)用于圖像處理和模式識(shí)別領(lǐng)域的新方法。本文將為大家介紹Python圖像形態(tài)學(xué)處理中的開運(yùn)算、閉運(yùn)算和梯度運(yùn)算,感興趣的可以了解一下2022-06-06

