Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输

简介: 使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。

设计思路

运行思路如下
由于在做人脸视频检测的项目的时候需要将检测的人脸区域全部保存下来,并发送到服务器端(用虚拟机来代替),来进行人脸对比,整个代码设计思路如下。
客户端

  • save_file_dir作用是读取文件路径(返回每一个图片的具体路径)
  • file_deal作用是将图片路径进行读取,返回字节数
  • send就是发送图片带服务器的过程,首先肯定要先和服务器进行connect,然后再确认一下服务器get到文件长度和文件名数据,就可以进行发送图片了。

服务器端:

  • 只需要定义一个函数,用于和客户端进行端口链接,通过sock.accept() 得到客户端发送的数据和ip和port,然后通过decode().split(’|’)获取到客户端发送的东西(包括字节长度和文件路径),最后通过创建一个图片,把图片信息写入进行就可以了。

代码实现

#===============================================================
#           客户端

import socket,os
def save_file_dir(file_dir):
    import glob, os
    filenames = glob.glob(os.path.join(file_dir, '*.jpg'))
    nums = len(filenames)
    print('共有{}张图片'.format(nums))
    return filenames

def read_pic(path1):
    if os.path.exists(path1):
        print('path exist.......')
    dirnames = sorted(os.listdir(path1))
    fullnames=[]
    for dirname in dirnames:
        dirfullname=os.path.join(path1,dirname)
        fullnames.append(dirfullname)
    print('the file is {}'.format(len(dirnames)))
    return dirnames,fullnames

def send(IMAGE_PATH):
    ip_addr = ("10.16.97.201", 8888)
    filepaths,fullnames=read_pic(IMAGE_PATH)
    for photo in fullnames:
        print('sending {}'.format(photo))
        data = file_deal(photo)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect(ip_addr)
        sock.send('{}|{}'.format(len(data), photo).encode())  # 默认编码 utf-8,发送文件长度和文件名
        reply = sock.recv(1024)
        if 'ok' == reply.decode():  # 确认一下服务器get到文件长度和文件名数据
            go = 0
            total = len(data)
            while go < total:  # 发送文件
                data_to_send = data[go:go + 1024]
                sock.send(data_to_send)
                go += len(data_to_send)
            reply = sock.recv(1024)
            if 'copy' == reply.decode():
                print('{} send successfully'.format(photo))
        sock.close()  # 由于tcp是以流的形式传输数据,我们无法判断开头和结尾,简单的方法是没传送一个文件,就使用一个socket,但是这样是消耗计算机的资源,博主正在探索更好的方法,有机会交流一下

def file_deal(file_path):  # 读取文件的方法
    # open image
    myfile = open(file_path, 'rb')
    bytes = myfile.read()
    return bytes

IMAGE_PATH = '/home/z/Documents/face_detect_yolov4_yolov4tiny_ssd-master/yolov4_cam_result/'
send(IMAGE_PATH)
#===============================================================
#           服务端
# 先通过服务器端运行,在通过客户端运行(传送图片来自客户端),需要两者的地址和端口号都来自于服务器端

import socket
import random
import os
def server():
    port=8888
    ip_addr = ("10.16.97.201", port)
    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((ip_addr))   #绑定端口
    sock.listen(3)     #监听端口
    print('waiting for file...')
    while True:
        sc,sc_name = sock.accept()    #当有请求到指定端口是 accpte()会返回一个新的socket和对方主机的(ip,port)
        print('收到{}请求'.format(sc_name))
        infor = sc.recv(1024)       #首先接收一段数据,这段数据包含文件的长度和文件的名字,使用|分隔,具体规则可以在客户端自己指定
        length,file_name = infor.decode().split('|')
        (filepath,tempfilename)=os.path.split(file_name)
        (shotname,extension)=os.path.splitext(tempfilename)
        #portion = os.path.splitext(dirpath)  # 把文件名拆分为名字和后缀
        #print(portion)
        if length and file_name:
            image_path='F:/pycharm/client/'
            os.makedirs(os.path.dirname(image_path),exist_ok=True)
            newfile = open(image_path+shotname+'.jpg','wb')  #这里可以使用从客户端解析出来的文件名
            print('length {},filename {}'.format(length,file_name))
            sc.send(b'ok')   #表示收到文件长度和文件名
            file = b''
            total = int(length)
            get = 0
            while get < total:         #接收文件
                data = sc.recv(1024)
                file += data
                get = get + len(data)
            print('应该接收{},实际接收{}'.format(length,len(file)))
            if file:
                print('acturally length:{}'.format(len(file)))
                newfile.write(file[:])
                newfile.close()
                sc.send(b'copy')    #告诉完整的收到文件了
        sc.close()
server()

传输结果

在这里插入图片描述

在这里插入图片描述

#!/usr/bin/python
# -*-coding:utf-8 -*-
import socket
import cv2
import numpy
from time import sleep

# socket.AF_INET 用于服务器与服务器之间的网络通信
# socket.SOCK_STREAM 代表基于TCP的流式socket通信
# 连接服务端
ip_addr = ("10.16.55.26", 1818)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(ip_addr)

# 从摄像头采集图像
# 参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频
capture = cv2.VideoCapture(0,cv2.CAP_DSHOW)
# capture.read() 按帧读取视频
# ret,frame 是capture.read()方法的返回值
# 其中ret是布尔值,如果读取帧正确,返回True;如果文件读到末尾,返回False。
# frame 就是每一帧图像,是个三维矩阵
ret, frame = capture.read()
i=25
while ret:
    ret, frame = capture.read()
    if ret:
        i+=1
    else:
        break
    # 首先对图片进行编码,因为socket不支持直接发送图片
    # '.jpg'表示把当前图片frame按照jpg格式编码
    # result, img_encode = cv2.imencode('.jpg', frame)
    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 50]
    img_encode = cv2.imencode('.jpg', frame, encode_param)[1]
    data = numpy.array(img_encode)
    name='{}.jpg'.format(i)
    sock.send('{}|{}'.format(len(data), name).encode())  # 默认编码 utf-8,发送文件长度和文件名
    reply = sock.recv(1024)
    if 'ok' == reply.decode():  # 确认一下服务器get到文件长度和文件名数据
        go = 0
        total = len(data)
        # 然后一个字节一个字节发送编码的内容
        while go < total:  # 发送文件
            data_to_send = data[go:go + 1024]
            sock.send(data_to_send)
            go += len(data_to_send)
        reply = sock.recv(1024)
        if 'copy' == reply.decode():
            print('{} send successfully'.format(name))
    # sleep(1)

    # cv2.resize(frame, (640, 480))
    # str_data = data.tostring()
    # 首先发送图片编码后的长度
    # sock.send(str(len(stringData),decoding='utf8').ljust(16))
    # 发送
    # sock.send(str(len(str_data)).ljust(16).encode())
    # 然后一个字节一个字节发送编码的内容
    # 如果是python对python那么可以一次性发送,如果发给c++的server则必须分开发因为编码里面有字符串结束标志位,c++会截断
    # for i in range(0, len(stringData)):
    #     sock.send(stringData[i])
    # sock.send(str_data)

    # ret, frame = capture.read()
    # cv2.resize(frame, (640, 480))

sock.close()
cv2.destroyAllWindows()
目录
相关文章
|
7月前
|
人工智能 JavaScript API
零基础构建MCP服务器:TypeScript/Python双语言实战指南
作为一名深耕技术领域多年的博主摘星,我深刻感受到了MCP(Model Context Protocol)协议在AI生态系统中的革命性意义。MCP作为Anthropic推出的开放标准,正在重新定义AI应用与外部系统的交互方式,它不仅解决了传统API集成的复杂性问题,更为开发者提供了一个统一、安全、高效的连接框架。在过去几个月的实践中,我发现许多开发者对MCP的概念理解透彻,但在实际动手构建MCP服务器时却遇到了各种技术壁垒。从环境配置的细节问题到SDK API的深度理解,从第一个Hello World程序的调试到生产环境的部署优化,每一个环节都可能成为初学者的绊脚石。因此,我决定撰写这篇全面的实
1745 67
零基础构建MCP服务器:TypeScript/Python双语言实战指南
|
5月前
|
机器学习/深度学习 编解码 Python
Python图片上采样工具 - RealESRGANer
Real-ESRGAN基于深度学习实现图像超分辨率放大,有效改善传统PIL缩放的模糊问题。支持多种模型版本,推荐使用魔搭社区提供的预训练模型,适用于将小图高质量放大至大图,放大倍率越低效果越佳。
417 3
|
11月前
|
移动开发 JavaScript 前端开发
精通服务器推送事件(SSE)与 Python 和 Go 实现实时数据流 🚀
服务器推送事件(SSE)是HTML5规范的一部分,允许服务器通过HTTP向客户端实时推送更新。相比WebSocket,SSE更轻量、简单,适合单向通信场景,如实时股票更新或聊天消息。它基于HTTP协议,使用`EventSource` API实现客户端监听,支持自动重连和事件追踪。虽然存在单向通信与连接数限制,但其高效性使其成为许多轻量级实时应用的理想选择。文中提供了Python和Go语言的服务器实现示例,以及HTML/JavaScript的客户端代码,帮助开发者快速集成SSE功能,提升用户体验。
|
5月前
|
机器学习/深度学习 文字识别 Java
Python实现PDF图片OCR识别:从原理到实战的全流程解析
本文详解2025年Python实现扫描PDF文本提取的四大OCR方案(Tesseract、EasyOCR、PaddleOCR、OCRmyPDF),涵盖环境配置、图像预处理、核心识别与性能优化,结合财务票据、古籍数字化等实战场景,助力高效构建自动化文档处理系统。
1443 0
|
6月前
|
人工智能 自然语言处理 安全
Python构建MCP服务器:从工具封装到AI集成的全流程实践
MCP协议为AI提供标准化工具调用接口,助力模型高效操作现实世界。
1201 1
|
9月前
|
数据采集 Web App开发 JavaScript
基于Selenium的Python爬虫抓取动态App图片
基于Selenium的Python爬虫抓取动态App图片
661 68
|
7月前
|
安全 Linux Shell
使用SCP命令在CentOS 7上向目标服务器传输文件
以上步骤是在CentOS 7系统上使用SCP命令进行文件传输的基础,操作简洁,易于理解。务必在执行命令前确认好各项参数,尤其是目录路径和文件名,以避免不必要的传输错误。
736 17
|
10月前
|
Python
使用Python实现multipart/form-data文件接收的http服务器
至此,使用Python实现一个可以接收 'multipart/form-data' 文件的HTTP服务器的步骤就讲解完毕了。希望通过我的讲解,你可以更好地理解其中的逻辑,另外,你也可以尝试在实际项目中运用这方面的知识。
473 69
|
9月前
|
人工智能 安全 Shell
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
Jupyter MCP服务器基于模型上下文协议(MCP),实现大型语言模型与Jupyter环境的无缝集成。它通过标准化接口,让AI模型安全访问和操作Jupyter核心组件,如内核、文件系统和终端。本文深入解析其技术架构、功能特性及部署方法。MCP服务器解决了传统AI模型缺乏实时上下文感知的问题,支持代码执行、变量状态获取、文件管理等功能,提升编程效率。同时,严格的权限控制确保了安全性。作为智能化交互工具,Jupyter MCP为动态计算环境与AI模型之间搭建了高效桥梁。
623 2
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
|
7月前
|
安全 Linux 网络安全
Python极速搭建局域网文件共享服务器:一行命令实现HTTPS安全传输
本文介绍如何利用Python的http.server模块,通过一行命令快速搭建支持HTTPS的安全文件下载服务器,无需第三方工具,3分钟部署,保障局域网文件共享的隐私与安全。
1660 0

推荐镜像

更多