九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
python TCP通信詳解

文章目錄

  • TCP簡(jiǎn)介

    • TCP介紹

    • TCP特點(diǎn)

    • TCP與UDP的不同點(diǎn)

    • tcp通信模型

    • 1. 面向連接

    • 2. 可靠傳輸

  • TCP網(wǎng)絡(luò)程序

    • tcp客戶端和服務(wù)端

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

  • TCP服務(wù)器

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

    • tcp注意點(diǎn)

  • 文件下載器

TCP簡(jiǎn)介

TCP介紹

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

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

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

TCP特點(diǎn)

1. 面向連接

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

雙方間的數(shù)據(jù)傳輸都可以通過(guò)這一個(gè)連接進(jìn)行。

完成數(shù)據(jù)交換后,雙方必須斷開(kāi)此連接,以釋放系統(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)沒(mé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ù)來(lái)檢驗(yàn)數(shù)據(jù)是否有錯(cuò)誤;在發(fā)送和接收時(shí)都要計(jì)算校驗(yàn)和。

4) 流量控制和阻塞管理

流量控制用來(lái)避免主機(jī)發(fā)送得過(guò)快而使接收方來(lái)不及完全收下。

TCP與UDP的不同點(diǎn)

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

tcp通信模型

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


TCP網(wǎng)絡(luò)程序

tcp客戶端和服務(wù)端

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

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

tcp的客戶端要比服務(wù)器端簡(jiǎn)單很多,如果說(shuō)服務(wù)器端是需要自己買手機(jī)、查手機(jī)卡、設(shè)置鈴聲、等待別人打電話流程的話,那么客戶端就只需要找一個(gè)電話亭,拿起電話撥打即可,流程要少很多

客戶端一般不綁定端口

from socket import *

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

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

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

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

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

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

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

網(wǎng)絡(luò)調(diào)試助手:https://www.cr173.com/soft/746079.html

TCP服務(wù)器

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

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

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

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

  3. listen使套接字變?yōu)榭梢员粍?dòng)鏈接 (接電話服務(wù)要開(kāi)通)套接字默認(rèn)是連接別人,需要化主動(dòng)為被動(dòng)

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

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

from socket import *

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

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

# 綁定
tcp_server_socket.bind(address)

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

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

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

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

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

tcp注意點(diǎn)

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

  • tcp客戶端一般不綁定,因?yàn)槭侵鲃?dòng)鏈接服務(wù)器,所以只要確定好服務(wù)器的ip、port等信息就好,本地客戶端可以隨機(jī)

  • tcp服務(wù)器中通過(guò)listen可以將socket創(chuàng)建出來(lái)的主動(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è)套接字用來(lái)標(biāo)記這個(gè)客戶端,單獨(dú)為這個(gè)客戶端服務(wù)

  • listen后的套接字是被動(dòng)套接字,用來(lái)接收新的客戶端的鏈接請(qǐ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解堵塞,并且返回的長(zhǎng)度為0,就是recv()返回為空, sendto不能發(fā)送空消息,因此服務(wù)器可以通過(guò)返回?cái)?shù)據(jù)的長(zhǎng)度來(lái)區(qū)別客戶端是否已經(jīng)下線

文件下載器

服務(wù)器

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("沒(méi)有下載的文件:%s" % file_name)


def main():

    if len(sys.argv) != 2:
        print("請(qǐng)按照如下方式運(yùn)行:python3 xxx.py 7890")
        return
    else:
        # 運(yùn)行方式為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)
    # 將主動(dòng)套接字變?yōu)楸粍?dòng)套接字
    tcp_server_socket.listen(128)

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

    # 關(guān)閉監(jiān)聽(tīng)套接字
    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("請(qǐng)輸入服務(wù)器ip:")
    server_port = int(input("請(qǐng)輸入服務(wù)器port:"))

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

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

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

    # 接收對(duì)方發(fā)送過(guò)來(lái)的數(shù)據(jù),最大接收1024個(gè)字節(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)

    # 關(guān)閉套接字
    tcp_client_socket.close()


if __name__ == "__main__":
    main()
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android中的TCP/IP,HTTP的認(rèn)識(shí)
企業(yè)即時(shí)通訊系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
通信掃盲
深入淺出-iOS的TCP/IP協(xié)議族剖析&&Socket
讀懂Java中的Socket編程
TCP/IP UDP HTTP Socket釋疑
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服