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

posted @ 2022-06-17 09:04  离人怎挽_wdj  阅读(904)  评论(0编辑  收藏  举报