ubuntu下使用docker和socket进行数据交互记录

news2024/12/23 17:00:56

ubuntu下使用docker和socket进行数据交互记录

概述:主要实现了在宿主机上通过8000端口传递一张图像给docker镜像,然后镜像中处理后,通过8001端口回传处理后的图像给宿主机。

第一章、构建镜像

一、dockerfile文件

1.拉取ubuntu20.04镜像
基于ubuntu20.04进行构建,拉取ubuntu20.04的指令如下:

sudo docker pull ubuntu:20.04

2.编写dockerfile文件
dockerfile写入如下:

# Dockerfile

# Base images 基础镜像

FROM ubuntu:20.04

# MAINTAINER 维护者信息
maintainer chenjun_1241370589@qq.com
# 设置超时
ENV PIP_DEFAULT_TIMEOUT=100 
# 设置环境变量以避免手动选择时区
ENV DEBIAN_FRONTEND=noninteractive


#RUN 执行以下命令
RUN apt update
RUN apt install python3 python3-pip -y
RUN apt-get install nano
# 安装必要的系统依赖项
RUN apt-get update && apt-get install -y \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libxrender-dev
RUN pip3 install --upgrade pip setuptools
RUN pip3 cache purge
RUN pip3 install opencv-python==4.5.5.62 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 安装 OpenCV  
RUN apt-get update && apt-get install -y \   
    libgl1-mesa-glx  # 安装 OpenGL 库  
# 其他依赖和设置


RUN pip3 install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple 
RUN apt install libgl1-mesa-glx
RUN mkdir -p /data/code/

#拷贝文件至工作文件夹
COPY test.py /data/code/test.py

#工作目录
WORKDIR /data/code/

#容器启动时执行的命令
CMD ["python3","test.py"]
二、编写docker内运行文件

1.新建test.py文件
test.py文件将被拷贝进镜像中,作为镜像内部运行文件。写入如下:

import cv2  # 导入OpenCV库
import numpy as np  # 导入NumPy库
import socket  # 导入socket库
import struct  # 导入struct库
import time

def receive_image():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP/IP套接字
    server_socket.bind(('0.0.0.0', 8000))  # 绑定到本地地址和端口8000
    server_socket.listen(1)  # 监听连接
    
    print("Waiting for connection...")  # 打印等待连接信息
    client_socket, addr = server_socket.accept()  # 接受连接
    print(f"Connected to {addr}")  # 打印连接地址

    data = b""  # 初始化数据变量
    payload_size = struct.calcsize("L")  # 获取消息大小的字节数

    while len(data) < payload_size:  # 接收消息大小
        data += client_socket.recv(4096)

    packed_msg_size = data[:payload_size]  # 获取打包的消息大小
    data = data[payload_size:]  # 剩余数据
    msg_size = struct.unpack("L", packed_msg_size)[0]  # 解包消息大小

    while len(data) < msg_size:  # 接收完整消息
        data += client_socket.recv(4096)

    frame_data = data[:msg_size]  # 获取图像数据
    
    frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)  # 解码图像
    
    client_socket.close()  # 关闭客户端套接字
    server_socket.close()  # 关闭服务器套接字
    
    return frame  # 返回图像

def process_image(image):
    height, width = image.shape[:2]  # 获取图像高度和宽度
    new_height, new_width = height // 2, width // 2  # 计算新高度和宽度
    print("Process_image ok !")
    return cv2.resize(image, (new_width, new_height))  # 调整图像大小

def send_image(image):
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP/IP套接字
    for _ in range(5):  # 尝试5次连接
        try:
            client_socket.connect(('172.17.0.1', 8001))  # 连接到指定地址和端口
            break
        except ConnectionRefusedError:
            print("Connection refused, retrying...")
            time.sleep(2)  # 等待2秒后重试
    else:
        print("Failed to connect after 5 attempts")
        return

    _, img_encoded = cv2.imencode('.jpg', image)  # 编码图像为JPEG格式
    data = img_encoded.tobytes()  # 转换为字节数据

    client_socket.sendall(struct.pack("L", len(data)) + data)  # 发送数据
    client_socket.close()  # 关闭客户端套接字

if __name__ == "__main__":
    while True:
        # 接收图像
        received_image = receive_image()
        
        # 处理图像
        processed_image = process_image(received_image)
        
        # 发送处理后的图像
        send_image(processed_image)

其中client_socket.connect((‘172.17.0.1’, 8001)) # 连接到指定地址和端口这一行中的ip需要在宿主机运行指令:

ip addr show docker0

在这里插入图片描述
将inet后的ip填入代码中。

三、构建镜像

宿主机终端输入:

sudo docker build -t python_socket2 . -f Dockerfile

其中“python_socket2”是我自己创建的名字,自行修改。
在这里插入图片描述

第二章、宿主机代码

一、交互代码

在宿主机中写入test1.py代码,这里图像处理部分只对图像进行尺寸减半的操作,代码如下:

import cv2
import numpy as np
import socket
import struct

def send_image(image_path):
    # 读取图像
    image = cv2.imread(image_path)
    if image is None:
        print(f"无法读取图像: {image_path}")
        return

    # 创建TCP/IP套接字
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('localhost', 8000))  # 连接到Docker容器的8000端口

    # 编码图像为JPEG格式
    _, img_encoded = cv2.imencode('.jpg', image)
    data = img_encoded.tobytes()

    # 发送数据
    client_socket.sendall(struct.pack("L", len(data)) + data)
    client_socket.close()

    print("图像已发送")

def receive_processed_image():
    # 创建TCP/IP套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('0.0.0.0', 8001))  # 绑定到本地地址和端口8001
    server_socket.listen(1)

    print("等待接收处理后的图像...")
    client_socket, addr = server_socket.accept()
    print(f"已连接到 {addr}")

    data = b""
    payload_size = struct.calcsize("L")

    while len(data) < payload_size:
        data += client_socket.recv(4096)

    packed_msg_size = data[:payload_size]
    data = data[payload_size:]
    msg_size = struct.unpack("L", packed_msg_size)[0]

    while len(data) < msg_size:
        data += client_socket.recv(4096)

    frame_data = data[:msg_size]
    
    # 解码图像
    frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)
    
    client_socket.close()
    server_socket.close()
    
    return frame

if __name__ == "__main__":
    image_path = "/home/cj/work/Docker/Yolov5DnnImage/bus.jpg"  # 替换为实际的图像路径
    send_image(image_path)
    
    processed_image = receive_processed_image()
    
    # 显示处理后的图像
    #cv2.imshow("Processed Image", processed_image)
    #cv2.waitKey(0)
    #cv2.destroyAllWindows()

    # 保存处理后的图像
    cv2.imwrite("processed_image.jpg", processed_image)
    print("处理后的图像已保存为 processed_image.jpg")

图像输入地址自行修改。

第三章、交互使用

一、docker端

在宿主机终端输入:

sudo docker run -p 8000:8000 -i -t python_socket2:latest

这里的“python_socket2:latest”修改成自己的镜像。
查看镜像宿主机终端输入:

sudo docker images

在这里插入图片描述

二、宿主机端

运行test1.py文件
在这里插入图片描述
同时在docker端也会有输出:
在这里插入图片描述
在宿主机当前工作目录下也会生成对应的图像。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2039936.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端面试】挖掘做过的nextJS项目(下)

https://blog.csdn.net/weixin_43342290/article/details/141170360?spm1001.2014.3001.5501文章浏览阅读105次。需求:快速搭建宣传官网1.适应pc、移动端2.基本的路由跳转3.页面渲染优化4.宣传的图片、视频资源的加载优化5.seo优化全栈react web应用、tailwind css原子工具的支…

Python中的多行字符串和文档字符串

Python中的多行字符串和文档字符串 Python中&#xff0c;多行字符串和文档字符串都使用三引号&#xff08;""" 或 &#xff09;来定义。都可以跨越多行而不需要使用行连接符&#xff08;\&#xff09;。 多行字符串和文档字符串都可以利用转义符来调整格式——…

vue3.0脚手架、路由、Element Plus安装案例:收录于Vue 3.0 后台管理系统案例

目录 环境配置 Vue 3.0 脚手架&#xff08;Vite&#xff09;安装 node版本查询与切换 创建一个vue应用 Vue Router安装 安装vue-router4 配置路由 安装配置 展示路由 Element UI安装 安装element-plus 引入element-plus 使用element-plus 用户登录 环境配置 Vue 3…

HarmonyOS(51) 应用沙箱目录和Context获取文件路径

文件目录 应用沙箱目录沙箱目录的分类应用文件目录结构应用文件路径详细说明ApplicationContext获取应用文件路径通过AbilityStageContext、UIAbilityContext、ExtensionContext获取HAP级别的应用文件路径切换el1和el2AreaMode简介 参考资料 应用沙箱目录 沙箱目录的分类 如下…

CUDA+tensorflow+python+vscode在GPU下环境安装及问题汇总与解答

2024.8.14 因为要做深度学习&#xff0c;需要安装tensorflowgpu的环境&#xff0c;每次都搞不好整的很生气&#xff0c;本次将安装过程中参考的一些大佬的博客和安装过程中遇到的问题及解决方案总结一下&#xff0c;希望以后不要在这件事情上浪费时间。安装环境其实也没有想象中…

迁移学习代码复现

一、前言 说来可能令人难以置信,迁移学习技术在实践中是非常简单的,我们仅需要保留训练好的神经网络整体或者部分网络,再在使用迁移学习的情况下把保留的模型重新加载到内存中,就完成了迁移的过程。之后,我们就可以像训练普通神经网络那样训练迁移过来的神经网络了。 我们…

浅谈SIMD、向量化处理及其在StarRocks中的应用

前言 单指令流多数据流(SIMD)及其衍生出来的向量化处理技术已经有了相当的历史&#xff0c;并且也是高性能数据库、计算引擎、多媒体库等组件的标配利器。笔者在两年多前曾经做过一次有关该主题的内部Geek分享&#xff0c;但可能是由于这个topic离实际研发场景比较远&#xff0…

使用大模型从政府公文中抽取指标数据

文章目录 介绍流程结构介绍相关文本筛选大模型 few-shot大模型抽取结果 介绍 本文使用LangChain 结合 Ollama的qwen2:7b模型&#xff0c;抽取出全国市级单位每一年预期生产总值指标。 Ollama的qwen2:7b&#xff0c;显存占用只有5G左右&#xff0c;适合大多数消费级显卡运行。…

华为云Api调用怎么生成Authorization鉴权信息,StringToSign拼接流程

请求示例 Authorization 为了安全&#xff0c;华为云的 Api 调用都是需要在请求的 Header 中携带 Authorization 鉴权的&#xff0c;这个鉴权15分钟内有效&#xff0c;超过15分钟就不能用了&#xff0c;而且是需要调用方自己手动拼接的。 Authorization的格式为 OBS 用户AK:…

zabbix agent 可用性 为 灰色

解决zabbix可用性为灰色状态 配置–》模板–》选择模板&#xff0c; 之后正常。

排序: 插入\希尔\选择\归并\冒泡\快速\堆排序实现

1.排序的概念及应用 1.1概念 排序:所谓排序&#xff0c;就是一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 1.2运用 购物筛选排序&#xff1a; 1.3常见排序算法 2.实现常见的排序算法 int a[ {5,3,9,6,2,4,7,1,8}; 2…

MySQL数据库专栏(三)数据库服务维护操作

1、界面维护&#xff0c;打开服务窗口找到MySQL服务&#xff0c;右键单击可对服务进行启动、停止、重启等操作。 选择属性&#xff0c;还可以设置启动类型为自动、手动、禁用。 2、指令维护 卸载服务&#xff1a;sc delete [服务名称] 例如&#xff1a;sc delete MySQL 启动服…

嵌入式软件开发学习一:软件安装(保姆级教程)

资源下载&#xff1a; 江协科技提供&#xff1a; 资料下载 一、安装Keil5 MDK 1、双击.EXE文件&#xff0c;开始安装 2、 3、 4、此处尽量不要安装在C盘&#xff0c;安装路径选择纯英文&#xff0c;防止后续开发报错 5、 6、 7、弹出来的窗口全部关闭&#xff0c;进入下一步&a…

STM32(一):新建工程

stm32f10x.h文件&#xff1a;描述stm32有哪些寄存器&#xff08;外围&#xff09;和它对应的地址。stm32由内核和内核外围的设备组成的&#xff0c;内核寄存器描述和外围寄存器描述文件存储位置不在一起core_cm3.h core_cm3.c内核寄存器描述文件。mic.c内核库函数 stm32f10x_co…

【初阶数据结构】通讯录项目(可用作课程设计)

文章目录 概述1. 通讯录的效果2. SeqList.h3. Contact.h4. SeqList.c5. Contact.c6. test.c 概述 通讯录项目是基于顺序表这个数据结构来实现的。如果说数组是苍蝇小馆&#xff0c;顺序表是米其林的话&#xff0c;那么通讯录就是国宴。 换句话说&#xff0c;通讯录就是顺序表…

pycharm windows/mac 指定多版本python

一、背景 工作中经常会使用不同版本的包&#xff0c;如同时需要tf2和tf1&#xff0c;比较新的tf2需要更高的python版本才能安装&#xff0c;而像tf1.5 需要低版本的python 才能安装&#xff08;如 python3.6&#xff09;,所以需要同时安装多个版本。 二、安装多版本python py…

会员系统开发,检测按钮位置,按钮坐标,弹出指定位置对话框-SAAS 本地化及未来之窗行业应用跨平台架构

一 获取元素坐标 var 按钮_obj document.querySelector(#未来之窗玄武id);var 按钮_rect 按钮_obj.getBoundingClientRect()console.log(按钮_rect);输出结果 bottom : 35 height : 21 left : 219.921875 right : 339.921875 top : 14 width : 120 x : 219.921875 y…

R语言统计分析——组间差异的非参数检验

参考资料&#xff1a;R语言实战【第2版】 如果数据无法满足t检验或ANOVA的参数假设&#xff0c;可以转而使用非参数检验。举例来说&#xff0c;若结果变量在本质上就严重偏倚或呈现有序关系&#xff0c;那么可以考虑非参数检验。 1、两组的比较 若两组数据独立&#xff0c;可以…

大厂进阶五:React源码解析之Diff算法

本文主要针对React源码进行解析&#xff0c;内容有&#xff1a; 1、Diff算法原理、两次遍历 一、Diff源码解析 以下是关于 React Diff 算法的详细解析及实例&#xff1a; 1、React Diff 算法的基本概念和重要性 1.1 概念 React Diff 算法是 React 用于比较虚拟 DOM 树之间…

初识C++ · 类型转换

目录 前言&#xff1a; 1 C中的类型转换 1.1 static_cast 1.2 reinterpret_cast 1.3 const_cast 1.4 dynamic_cast 前言&#xff1a; C可以说是恨死了隐式类型转换&#xff0c;你可能会疑问了&#xff0c;为什么&#xff1f;不是单参数隐式类型转换为自定义类型的时候人…