您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么在python中實(shí)現(xiàn)tcp,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
1、云計(jì)算,典型應(yīng)用OpenStack。2、WEB前端開發(fā),眾多大型網(wǎng)站均為Python開發(fā)。3.人工智能應(yīng)用,基于大數(shù)據(jù)分析和深度學(xué)習(xí)而發(fā)展出來的人工智能本質(zhì)上已經(jīng)無法離開python。4、系統(tǒng)運(yùn)維工程項(xiàng)目,自動(dòng)化運(yùn)維的標(biāo)配就是python+Django/flask。5、金融理財(cái)分析,量化交易,金融分析。6、大數(shù)據(jù)分析。
TCP協(xié)議,傳輸控制協(xié)議(英語(yǔ):Transmission Control Protocol,縮寫為 TCP)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,由IETF的RFC 793定義。
TCP通信需要經(jīng)過創(chuàng)建連接、數(shù)據(jù)傳送、終止連接三個(gè)步驟。
TCP通信模型中,在通信開始之前,一定要先建立相關(guān)的鏈接,才能發(fā)送數(shù)據(jù),類似于生活中,"打電話""
1. 面向連接
通信雙方必須先建立連接才能進(jìn)行數(shù)據(jù)的傳輸,雙方都必須為該連接分配必要的系統(tǒng)內(nèi)核資源,以管理連接的狀態(tài)和連接上的傳輸。
雙方間的數(shù)據(jù)傳輸都可以通過這一個(gè)連接進(jìn)行。
完成數(shù)據(jù)交換后,雙方必須斷開此連接,以釋放系統(tǒng)資源。
這種連接是一對(duì)一的,因此TCP不適用于廣播的應(yīng)用程序,基于廣播的應(yīng)用程序請(qǐ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í)體對(duì)已成功收到的包發(fā)回一個(gè)相應(yīng)的確認(rèn)(ACK);如果發(fā)送端實(shí)體在合理的往返時(shí)延(RTT)內(nèi)未收到確認(rèn),那么對(duì)應(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ā)送得過快而使接收方來不及完全收下。
面向連接(確認(rèn)有創(chuàng)建三方交握,連接已創(chuàng)建才作傳輸。)
有序數(shù)據(jù)傳輸
重發(fā)丟失的數(shù)據(jù)包
舍棄重復(fù)的數(shù)據(jù)包
無差錯(cuò)的數(shù)據(jù)傳輸
阻塞/流量控制
udp通信模型中,在通信開始之前,不需要建立相關(guān)的鏈接,只需要發(fā)送數(shù)據(jù)即可,類似于生活中,"寫信""
TCP通信模型
udp通信模型中,在通信開始之前,一定要先建立相關(guān)的鏈接,才能發(fā)送數(shù)據(jù),類似于生活中,"打電話""
tcp的客戶端要比服務(wù)器端簡(jiǎn)單很多,如果說服務(wù)器端是需要自己買手機(jī)、查手機(jī)卡、設(shè)置鈴聲、等待別人打電話流程的話,那么客戶端就只需要找一個(gè)電話亭,拿起電話撥打即可,流程要少很多
python創(chuàng)建tcp客戶端的代碼如下:
import socket def main(): # 1.創(chuàng)建套接字socket tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.連接服務(wù)器 dest_ip = input("請(qǐng)輸入服務(wù)器ip:") dest_port = int(input("請(qǐng)輸入服務(wù)器port:")) dest_addr = (dest_ip, dest_port) tcp_socket.connect(dest_addr) # 3. 接收/發(fā)送數(shù)據(jù) send_data = input("請(qǐng)輸入要發(fā)送的數(shù)據(jù):") tcp_socket.send(send_data.encode("utf-8")) # 接收服務(wù)器發(fā)送的數(shù)據(jù) recv_data = tcp_socket.recv(1024) print(recv_data.decode("utf-8")) # 4. 關(guān)閉套接字socket tcp_socket.close() if __name__ == "__main__": main()
在ubuntu的終端上執(zhí)行:
在網(wǎng)絡(luò)調(diào)試助手中啟動(dòng)tcp服務(wù)器進(jìn)行交互:
在程序中,如果想要完成一個(gè)tcp服務(wù)器的功能,需要的流程如下:
socket創(chuàng)建一個(gè)套接字
bind綁定ip和port
listen使套接字變?yōu)榭梢员粍?dòng)鏈接
accept等待客戶端的鏈接
recv/send接收發(fā)送數(shù)據(jù)
import socket def main(): # 1.創(chuàng)建套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2.綁定端口 addr = ("", 8866) tcp_server_socket.bind(addr) # 3.監(jiān)聽鏈接 tcp_server_socket.listen(128) # 4.接收別人的連接 # client_socket用來為這個(gè)客戶端服務(wù) client_socket, client_addr = tcp_server_socket.accept() # 5.接收對(duì)方發(fā)送的數(shù)據(jù) recv_data = client_socket.recv(1024) print("接收到的數(shù)據(jù):%s" % recv_data.decode("utf-8")) # 6.給對(duì)方發(fā)送數(shù)據(jù) client_socket.send("hahaha".encode("utf-8")) # 7.關(guān)閉套接字 client_socket.close() tcp_server_socket.close() if __name__ == "__main__": main()
在ubuntu的終端上執(zhí)行:
在網(wǎng)絡(luò)調(diào)試助手中啟動(dòng)tcp服務(wù)器進(jì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)套接字,用來接收新的客戶端的鏈接請(qǐng)求的,而accept返回的新套接字是標(biāo)記這個(gè)新客戶端的
關(guān)閉listen后的套接字意味著被動(dòng)套接字關(guān)閉了,會(huì)導(dǎo)致新的客戶端不能夠鏈接服務(wù)器,但是之前已經(jīng)鏈接成功的客戶端正常通信。
關(guān)閉accept返回的套接字意味著這個(gè)客戶端已經(jīng)服務(wù)完畢
當(dāng)客戶端的套接字調(diào)用close后,服務(wù)器端會(huì)recv解堵塞,并且返回的長(zhǎng)度為0,因此服務(wù)器可以通過返回?cái)?shù)據(jù)的長(zhǎng)度來區(qū)別客戶端是否已經(jīng)下線
關(guān)于怎么在python中實(shí)現(xiàn)tcp就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。