91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python怎么使用socket高效傳輸視頻數據幀

發布時間:2021-10-23 17:01:14 來源:億速云 閱讀:344 作者:iii 欄目:開發技術

本篇內容主要講解“python怎么使用socket高效傳輸視頻數據幀”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“python怎么使用socket高效傳輸視頻數據幀”吧!

目錄
  • 遇到的問題

  • 代碼問題記錄(需要代碼的可以直接文末)

  • 代碼

    • 客戶端clien.py

    • 服務端server.py

遇到的問題

網上找了一些代碼,都是只能建立一次socket傳輸一張圖片,然后斷開重新連重新傳。而建立一次socket代價不小,反復建立會非常消耗系統資源,因此嘗試自己通過一次socket連續傳輸多張圖片

代碼問題記錄(需要代碼的可以直接文末)

在做的過程中發現了一些問題:

socket在傳一張圖片時是以二進制流的形式傳輸,圖片的二進制流比較大,一般一次傳不完,要傳很多次。那么接受者是如何知道什么時候才停止接收這張圖片呢?那可以讓發送者在發圖之前先發一個頭信息,告訴接收者這個二進制流有多長,然后接收者通過這個來判斷是否傳完。

這個問題是最讓我致命的,由于發送者先發了一個頭信息,使用socket.send()函數,然后發送圖片也是要用socket.send()函數,接收端使用的是socket.recv(1024)函數,1024是緩存大。麻煩來了,由于發送者使用連續的兩個send,而socket.recv(1024)是有緩存的,他會把這兩個信息緩存到一起去,信息頭和圖片信息全被緩存了!!!這會直接導致代碼接收邏輯錯誤。我的做法是,不能有兩個send同時出現,那么我就在send中間加一個recv函數(阻塞函數),也就是發送者每發一個消息,接收者就立馬回復一個消息,這樣就保證了不會連續send

python怎么使用socket高效傳輸視頻數據幀 

代碼

由于項目存在兩種數據源,一種是可見光,一種是紅外,所以我最開始還要制作一個信息頭,每次發送的時候要告訴接收者這是什么類型的數據,然后再接收

制作不易,記得給個贊哈!

客戶端clien.py

服務器的地址
server_address = ('127.0.0.1', 8000)


def send(dir_name, data_format, file_name):
    # 與接收端建立socket通信
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # AF_INET(TCP/IP – IPv4)協議
    sock.connect(server_address)

    # 每次通信都帶一個通信頭,表明數據源的類型(紅外還是可見光),要保存數據幀的文件夾名file_name
    # 你可以不要數據格式,這里可以定義成你自己的形式,也算是一種安全機制
    sock.send('{}|{}'.format(data_format, file_name).encode())  # 默認編碼 utf-8,發送文件長度和文件名
    reply = sock.recv(1024)

    # 按照文件名排序,0.png,1.png
    file_list = os.listdir(dir_name)
    file_list.sort(key=lambda x: int(x[:-4]))
    if 'ok' == reply.decode():  # 確認一下服務器get到文件長度和文件名數據
        i = 0
        print(len(file_list))
        for file_name in file_list:
            data = file_deal(os.path.join(dir_name, file_name))
            sock.send('{}|{}'.format(len(data), file_name).encode())
            sock.recv(1024)
            go = 0
            total = len(data)
            while go < total:  # 發送文件
                data_to_send = data[go:go + total//2]
                sock.send(data_to_send)
                go += len(data_to_send)
            sock.recv(1024).decode()
            i += 1
            if i < len(file_list):
                sock.send(b'continue')
        sock.send(b'over')
        sock.close()
        sys.exit(0)


def file_deal(file_path):  # 讀取文件的方法
    mes = b''
    try:
        file = open(file_path, 'rb')
        mes = file.read()
    except:
        print('error{}'.format(file_path))
    else:
        file.close()
        return mes

服務端server.py

LOCAL_IP = '127.0.0.1'  # 本機測試使用ip,局域網中使用需更換ip
PORT = 8000  # 隨意指定一個端口

def server():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # socket.AF_INET 指ipv4  socket.SOCK_STREAM 使用tcp協議
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 設置端口
    sock.bind((LOCAL_IP, PORT))  # 綁定端口
    sock.listen(3)  # 監聽端口
    while True:
        sc, sc_name = sock.accept()  # 當有請求到指定端口是 accept()會返回一個新的socket和對方主機的(ip,port)
        print('收到{}機器請求'.format(sc_name))
        info = sc.recv(1024)  # 接受客戶端發來的協議頭,區分數據源
        # 安全處理:如果不是以這個協議頭開始,認為是非法接入,就直接斷掉。這里可以自己定義一些安全消息機制
        print(info)
        try:
            data_format, directory_name = info.decode().split("|")
            sc.send(b'ok')  # 表示收到文件長度和文件名
        except:
            print('協議頭不對,自動斷開連接')
            sc.close()
            continue

        if not os.path.exists(directory_name):
            os.mkdir(directory_name)
        # 協議頭正確之后,不斷接收發來的數據幀
        while True:
            head_info = sc.recv(1024)
            # print(data_info)
            length, file_name = head_info.decode().split('|')
            sc.send(b'ok')
            if length and file_name:
                print(file_name)
                newfile = open(os.path.join(directory_name, file_name), 'wb')  # 這里可以使用從客戶端解析出來的文件名
                file = b''
                total = int(length)
                get = 0
                while get < total:  # 接收文件
                    data = sc.recv(total//2)
                    file += data
                    get = get + len(data)
                sc.send(b'ok')
                print('應該接收{},實際接收{}'.format(length, len(file)))
                if file:
                    print('actually length:{}'.format(len(file)))
                    newfile.write(file[:])
                    newfile.close()
            reply = sc.recv(1024)
            if reply.decode() == "over":
                break

server()

啟動步驟

1.先啟動server.py
2.再啟動client.py

到此,相信大家對“python怎么使用socket高效傳輸視頻數據幀”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

闽侯县| 宁明县| 周口市| 嘉荫县| 察雅县| 高邑县| 禹城市| 鹤峰县| 朝阳市| 酉阳| 壤塘县| 凤山县| 太仓市| 昌都县| 鹿邑县| 高阳县| 名山县| 清水河县| 阳泉市| 高州市| 黎平县| 甘孜| 平和县| 乐平市| 凯里市| 车致| 平陆县| 潜山县| 郎溪县| 濮阳县| 巫溪县| 攀枝花市| 杭锦后旗| 双鸭山市| 长岭县| 六枝特区| 贵阳市| 聊城市| 延津县| 苏尼特右旗| 改则县|