• Python使用Socket进行图片传输


    server.py

    # -*- coding: utf-8 -*-
    # @Time    : 2022/6/15 16:24
    # @Author  : WDJ
    # @contact  : wei7wei@126.com
    import socket, os
    import json
    LOCAL_IP = '127.0.0.1'  # 本机测试使用ip,局域网中使用需更换ip
    PORT = 8098  # 随意指定一个端口
    
    
    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(100)  # 监听端口
        while True:
            sc, sc_name = sock.accept()  # 当有请求到指定端口是 accept()会返回一个新的socket和对方主机的(ip,port)
            print('收到{}机器请求'.format(sc_name))
            # 协议头正确之后,不断接收发来的数据帧
            while True:
                try:
                    info = sc.recv(1024)  # 接受客户端发来的协议头,区分数据源
                    # 安全处理:如果不是以这个协议头开始,认为是非法接入,就直接断掉。这里可以自己定义一些安全消息机制
                    print(info)
                    file_name, length, result_length = info.decode().split('|')
                    length = int(length)
                    result_length = int(result_length)
                    sc.send(b'ok')  # 表示收到文件长度和文件名
                except Exception as e:
                    print(str(e))
                    print('协议头不对,自动断开连接,等待下一次的连接')
                    sc.close()
                    break
                try:
                    if length and file_name and result_length:
                        get_result = 0
                        result_recive = b''
                        while get_result < result_length:
                            res_data = sc.recv(length // 2)
                            result_recive += res_data
                            get_result = get_result + len(res_data)
                        print('应该接收{},实际接收{}'.format(result_length, len(result_recive)))
                        sc.send(bytes("result接收完成", encoding="utf8"))
                        print(result_recive.decode('utf8'))
                        print(file_name)
                        newfile = open(os.path.join(r"D:\Users\zycx.vm148\Desktop", file_name), 'wb')  # 这里可以使用从客户端解析出来的文件名
                        recive_data = b''
                        get = 0
                        while get < length:  # 接收文件
                            data = sc.recv(length // 2)
                            recive_data += data
                            get = get + len(data)
                            print(f"--{get}---{length}----")
                        sc.send(bytes("image接收完成", encoding="utf8"))
                        print('应该接收{},实际接收{}'.format(length, len(recive_data)))
                        if recive_data:
                            print('actually length:{}'.format(len(recive_data)))
                            # recive_data = json.loads(recive_data.decode('utf8'))
                            print(recive_data)
                            newfile.write(recive_data[:])
                            newfile.close()
                    reply = sc.recv(1024)
                    print(reply)
                    if reply.decode('utf8') == "over":
                        continue
                except  Exception as e:
                    print(str(e))
                    break
    
    
    server()
    
    

    client.py

    # -*- coding: utf-8 -*-
    # @Time    : 2022/6/15 16:25
    # @Author  : WDJ
    # @contact  : wei7wei@126.com
    # 服务器的地址
    import socket, os, sys, json
    import time
    host = '127.0.0.1'
    port = 8098
    
    
    def doConnect(host, port):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # AF_INET(TCP/IP – IPv4)协议
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            sock.connect((host, port))
        except Exception as e:
            print(str(e))
        return sock
    
    
    def send(file_name, length, mes, cur_path, result_length, image_path,sock):
        # 与接收端建立socket通信
        # server_address = ('127.0.0.1',8098)
        # sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # AF_INET(TCP/IP – IPv4)协议
        # sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        # sock.connect(server_address)
        # 每次通信都带一个通信头,表明数据源的类型(红外还是可见光),要保存数据帧的文件夹名file_name
        # 你可以不要数据格式,这里可以定义成你自己的形式,也算是一种安全机制
        # if not sock:
        #     socket = socketClient.reconnect()
        #     socketClient.socket = socket
        #     sock = socket
        sock.send('{}|{}|{}'.format(file_name, length, result_length).encode())  # 默认编码 utf-8,发送文件长度和文件名
        reply = sock.recv(1024)
        result_flag = image_result = False
        if 'ok' == reply.decode():  # 确认一下服务器get到文件长度和文件名数据
            # 对图片的json数据进行传输
            fr = open(cur_path, 'rb')
            while True:
                b_result = fr.read(1024)
                if not b_result:
                    print('result send over...')
                    break
                sock.send(b_result)
            fr.close()
            ret_recive = sock.recv(1024).decode()
            if ret_recive == "result接收完成":
                result_flag = True
                fp = open(image_path, 'rb')  # 打开要传输的图片 对图片传输
                while True:
                    data = fp.read(1024)  # 读入图片数据
                    if not data:
                        print('image send over...')
                        break
                    sock.send(data)  # 以二进制格式发送图片数据
                image_recive = sock.recv(1024).decode()
                if image_recive == "image接收完成":
                    image_result = True
        if result_flag and image_result:
            os.remove(cur_path)
        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
    
    
    def find_json_files(path,sock):
        # 首先遍历当前目录所有文件及文件夹
        file_list = os.listdir(path)
        # 循环判断每个元素是否是文件夹还是文件,是文件夹的话,递归
        for file in file_list:
            # 利用os.path.join()方法取得路径全名,并存入cur_path变量,否则每次只能遍历一层目录
            cur_path = os.path.join(path, file)
            # 判断是否是特定文件名称
            if ".json" in file:
                with open(cur_path, 'rb') as f:
                    bytes_result = f.read()
                    image_json_data = json.loads(bytes_result.decode('utf8'))
                    image_path = image_json_data.get("path")
                    result = image_json_data.get("result")
                    file_name = image_path.split("\\")[-1]
                    mes = file_deal(image_path)  # 文件的二进制数据
                    print(len(mes))
                send(file_name, len(mes), mes, cur_path, len(bytes_result), image_path,sock)
        # sock.close()
    
    
    
    if __name__ == '__main__':
        path = r"D:\Users\zycx.vm148\Desktop\test1"
        sock = doConnect(host, port)
        while True:
            time.sleep(1)
            if (getattr(sock, '_closed') == False):    #当前socket服务端正在运行中
                print("当前socket服务端正在运行中")
                find_json_files(path,sock)
            else:
                print("重连------")
                sock = doConnect(host, port)
                find_json_files(path,sock)
    
    

    参考:https://www.jb51.net/article/226083.htm#_lab2_2_0

  • 相关阅读:
    Android sdk 下载路径
    centos修改用户用户组
    centos7 通过shell切换root用户
    java 服务上传图片到linux没有读写权限
    Mybatis第二天
    Mybatis第一天
    反射
    注解
    多线程第二天
    java---过滤器、监听器
  • 原文地址:https://www.cnblogs.com/weidaijie/p/16384415.html
Copyright © 2020-2023  润新知