久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

python TCP通信詳解

 大傻子的文淵閣 2022-11-14

TCP簡介

TCP介紹

TCP協(xié)議,傳輸控制協(xié)議(英語:Transmission Control Protocol,縮寫為 TCP)是一種面向連接的,、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,,由IETF的RFC 793定義。

TCP通信需要經(jīng)過創(chuàng)建連接,、數(shù)據(jù)傳送,、終止連接三個步驟。

TCP通信模型中,,在通信開始之前,,一定要先建立相關的鏈接,才能發(fā)送數(shù)據(jù),,類似于生活中,,“打電話”"

TCP特點

1. 面向連接

通信雙方必須先建立連接才能進行數(shù)據(jù)的傳輸,雙方都必須為該連接分配必要的系統(tǒng)內(nèi)核資源,,以管理連接的狀態(tài)和連接上的傳輸,。

雙方間的數(shù)據(jù)傳輸都可以通過這一個連接進行,。

完成數(shù)據(jù)交換后,雙方必須斷開此連接,,以釋放系統(tǒng)資源。

這種連接是一對一的,,因此TCP不適用于廣播的應用程序,,基于廣播的應用程序請使用UDP協(xié)議。

2. 可靠傳輸

1)TCP采用發(fā)送應答機制

TCP發(fā)送的每個報文段都必須得到接收方的應答才認為這個TCP報文段傳輸成功

2)超時重傳

發(fā)送端發(fā)出一個報文段之后就啟動定時器,,如果在定時時間內(nèi)沒有收到應答就重新發(fā)送這個報文段,。

TCP為了保證不發(fā)生丟包,就給每個包一個序號,,同時序號也保證了傳送到接收端實體的包的按序接收,。然后接收端實體對已成功收到的包發(fā)回一個相應的確認(ACK);如果發(fā)送端實體在合理的往返時延(RTT)內(nèi)未收到確認,,那么對應的數(shù)據(jù)包就被假設為已丟失將會被進行重傳,。

3)錯誤校驗

TCP用一個校驗和函數(shù)來檢驗數(shù)據(jù)是否有錯誤;在發(fā)送和接收時都要計算校驗和,。

4) 流量控制和阻塞管理

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

TCP與UDP的不同點

 TCPUDP
1TCP的傳輸是可靠傳輸。UDP的傳輸是不可靠傳輸,。
2TCP是基于連接的協(xié)議,,在正式收發(fā)數(shù)據(jù)前,必須和對方建立可靠的連接,。UDP是和TCP相對應的協(xié)議,,它是面向非連接的協(xié)議,它不與對方建立連接,,而是直接把數(shù)據(jù)包發(fā)送出去
3TCP是一種可靠的通信服務,,負載相對而言比較大,TCP采用套接字(socket)或者端口(port)來建立通信,。UDP是一種不可靠的網(wǎng)絡服務,,負載比較小。
4TCP和UDP結(jié)構(gòu)不同,,TCP包括序號,、確認信號、數(shù)據(jù)偏移,、控制標志(通常說的URG,、ACK、PSH,、RST,、SYN,、FIN)、窗口,、校驗和,、緊急指針、選項等信息,。UDP包含長度和校驗和信息,。
5TCP提供超時重發(fā),丟棄重復數(shù)據(jù),,檢驗數(shù)據(jù),,流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端,。UDP不提供可靠性,,它只是把應用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們能到達目的地,。
6TCP在發(fā)送數(shù)據(jù)包前在通信雙方有一個三次握手機制,,確保雙方準備好,在傳輸數(shù)據(jù)包期間,,TCP會根據(jù)鏈路中數(shù)據(jù)流量的大小來調(diào)節(jié)傳送的速率,,傳輸時如果發(fā)現(xiàn)有丟包,會有嚴格的重傳機制,,故而傳輸速度很慢,。UDP在傳輸數(shù)據(jù)報前不用在客戶和服務器之間建立一個連接,且沒有超時重發(fā)等機制,,故而傳輸速度很快,。
7TCP支持全雙工和并發(fā)的TCP連接,提供確認,、重傳與擁塞控制,。UDP適用于哪些系統(tǒng)對性能的要求高于數(shù)據(jù)完整性的要求,需要“簡短快捷”的數(shù)據(jù)交換,、需要多播和廣播的應用環(huán)境,。

tcp通信模型

udp通信模型中,在通信開始之前,,不需要建立相關的鏈接,,只需要發(fā)送數(shù)據(jù)即可,類似于生活中,,“寫信"
tcp通信模型中,,在通信開始之前,一定要先建立相關的鏈接,才能發(fā)送數(shù)據(jù),,類似于生活中,,“打電話”"

在這里插入圖片描述
在這里插入圖片描述

TCP網(wǎng)絡程序

tcp客戶端和服務端

所謂的服務器端:就是提供服務的一方,而客戶端,,就是需要被服務的一方

tcp客戶端構(gòu)建流程

tcp的客戶端要比服務器端簡單很多,,如果說服務器端是需要自己買手機、查手機卡,、設置鈴聲,、等待別人打電話流程的話,那么客戶端就只需要找一個電話亭,,拿起電話撥打即可,流程要少很多

客戶端一般不綁定端口

from socket import *

# 創(chuàng)建socket
tcp_client_socket = socket(AF_INET, SOCK_STREAM)

# 目的信息
server_ip = input("請輸入服務器ip:")
server_port = int(input("請輸入服務器port:"))

# 鏈接服務器
tcp_client_socket.connect((server_ip, server_port))

# 提示用戶輸入數(shù)據(jù)
send_data = input("請輸入要發(fā)送的數(shù)據(jù):")

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

# 接收對方發(fā)送過來的數(shù)據(jù),,最大接收1024個字節(jié)
recvData = tcp_client_socket.recv(1024)
print('接收到的數(shù)據(jù)為:', recvData.decode('gbk'))

# 關閉套接字
tcp_client_socket.close()
請輸入服務器ip:10.10.0.47
請輸入服務器port:8080
請輸入要發(fā)送的數(shù)據(jù):你好啊
接收到的數(shù)據(jù)為: 我很好,,你呢

網(wǎng)絡調(diào)試助手:https://www.cr173.com/soft/746079.html在這里插入圖片描述

TCP服務器

tcp服務器的構(gòu)建流程

如果想要完成一個tcp服務器的功能(聯(lián)通買座機接聽電話為例子),需要的流程如下:

  1. socket創(chuàng)建一個監(jiān)聽套接字 (聯(lián)通買座機)

  2. bind綁定ip和port (插電話卡)

  3. listen使套接字變?yōu)榭梢员粍渔溄?(接電話服務要開通)套接字默認是連接別人,,需要化主動為被動

  4. accept等待客戶端的鏈接 (等待別人給你打電話)
    返回新的通信套接字,,和地址 (主機把這個連接轉(zhuǎn)移給一個客服,然后給出來電顯示)

  5. recv/send接收發(fā)送數(shù)據(jù) (接通電話,,進行交流)

from socket import *

# 創(chuàng)建socket
tcp_server_socket = socket(AF_INET, SOCK_STREAM)

# 本地信息
address = ('', 7788)

# 綁定
tcp_server_socket.bind(address)

# 使用socket創(chuàng)建的套接字默認的屬性是主動的,,使用listen將其變?yōu)楸粍拥模@樣就可以接收別人的鏈接了
listen里的數(shù)字表征同一時刻能連接客戶端的程度.
tcp_server_socket.listen(128)

# 如果有新的客戶端來鏈接服務器,,那么就產(chǎn)生一個新的套接字專門為這個客戶端服務
# client_socket用來為這個客戶端服務
# tcp_server_socket就可以省下來專門等待其他新客戶端的鏈接
# clientAddr 是元組(ip,,端口)
client_socket, clientAddr = tcp_server_socket.accept()

# 接收對方發(fā)送過來的數(shù)據(jù),和udp不同返回的只有數(shù)據(jù)
recv_data = client_socket.recv(1024)  # 接收1024個字節(jié)
print('接收到的數(shù)據(jù)為:', recv_data.decode('gbk'))

# 發(fā)送一些數(shù)據(jù)到客戶端
client_socket.send("thank you !".encode('gbk')) #

# 關閉為這個客戶端服務的套接字,,只要關閉了,,就意味著為不能再為這個客戶端服務了,如果還需要服務,,只能再次重新連接
client_socket.close()

tcp注意點

  • tcp服務器一般情況下都需要綁定,,否則客戶端找不到這個服務器

  • tcp客戶端一般不綁定,因為是主動鏈接服務器,,所以只要確定好服務器的ip,、port等信息就好,本地客戶端可以隨機

  • tcp服務器中通過listen可以將socket創(chuàng)建出來的主動套接字變?yōu)楸粍拥?,這是做tcp服務器時必須要做的

  • 當客戶端需要鏈接服務器時,,就需要使用connect進行鏈接,udp是不需要鏈接的而是直接發(fā)送,,但是tcp必須先鏈接,,只有鏈接成功才能通信

  • 當一個tcp客戶端連接服務器時,服務器端會有1個新的套接字,這個套接字用來標記這個客戶端,,單獨為這個客戶端服務

  • listen后的套接字是被動套接字,,用來接收新的客戶端的鏈接請求的,而accept返回的新套接字是標記這個新客戶端的

  • 關閉listen后的套接字意味著被動套接字關閉了,,會導致新的客戶端不能夠鏈接服務器,,但是之前已經(jīng)鏈接成功的客戶端正常通信,因為accept返回了新的套接字。

  • 關閉accept返回的套接字意味著這個客戶端已經(jīng)服務完畢

  • 當客戶端的套接字調(diào)用close后,,服務器端會recv解堵塞,,并且返回的長度為0,就是recv()返回為空, sendto不能發(fā)送空消息,因此服務器可以通過返回數(shù)據(jù)的長度來區(qū)別客戶端是否已經(jīng)下線

文件下載器

服務器

from socket import *
import sys


def get_file_content(file_name):
    """獲取文件的內(nèi)容"""
    try:
        with open(file_name, "rb") as f:
            content = f.read()
        return content
    except:
        print("沒有下載的文件:%s" % file_name)


def main():

    if len(sys.argv) != 2:
        print("請按照如下方式運行:python3 xxx.py 7890")
        return
    else:
        # 運行方式為python3 xxx.py 7890
        port = int(sys.argv[1])


    # 創(chuàng)建socket
    tcp_server_socket = socket(AF_INET, SOCK_STREAM)
    # 本地信息
    address = ('', port)
    # 綁定本地信息
    tcp_server_socket.bind(address)
    # 將主動套接字變?yōu)楸粍犹捉幼?    tcp_server_socket.listen(128)

    while True:
        # 等待客戶端的鏈接,,即為這個客戶端發(fā)送文件
        client_socket, clientAddr = tcp_server_socket.accept()
        # 接收對方發(fā)送過來的數(shù)據(jù)
        recv_data = client_socket.recv(1024)  # 接收1024個字節(jié)
        file_name = recv_data.decode("utf-8")
        print("對方請求下載的文件名為:%s" % file_name)
        file_content = get_file_content(file_name)
        # 發(fā)送文件的數(shù)據(jù)給客戶端
        # 因為獲取打開文件時是以rb方式打開,,所以file_content中的數(shù)據(jù)已經(jīng)是二進制的格式,因此不需要encode編碼
        if file_content:
            client_socket.send(file_content)
        # 關閉這個套接字
        client_socket.close()

    # 關閉監(jiān)聽套接字
    tcp_server_socket.close()


if __name__ == "__main__":
    main()

客戶端

from socket import *


def main():

    # 創(chuàng)建socket
    tcp_client_socket = socket(AF_INET, SOCK_STREAM)

    # 目的信息
    server_ip = input("請輸入服務器ip:")
    server_port = int(input("請輸入服務器port:"))

    # 鏈接服務器
    tcp_client_socket.connect((server_ip, server_port))

    # 輸入需要下載的文件名
    file_name = input("請輸入要下載的文件名:")

    # 發(fā)送文件下載請求
    tcp_client_socket.send(file_name.encode("utf-8"))

    # 接收對方發(fā)送過來的數(shù)據(jù),,最大接收1024個字節(jié)(1K)
    recv_data = tcp_client_socket.recv(1024)
    # print('接收到的數(shù)據(jù)為:', recv_data.decode('utf-8'))
    # 如果接收到數(shù)據(jù)再創(chuàng)建文件,,否則不創(chuàng)建
    if recv_data:
        with open("[接收]"+file_name, "wb") as f:
            f.write(recv_data)

    # 關閉套接字
    tcp_client_socket.close()


if __name__ == "__main__":
    main()

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多