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, osfilenames = glob.glob(os.path.join(file_dir, '*.jpg'))nums = len(filenames)print('共有{}张图片'.format(nums))return filenamesdef 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,fullnamesdef 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 = 0total = 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 imagemyfile = open(file_path, 'rb')bytes = myfile.read()return bytesIMAGE_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=8888ip_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 = 0while get < total: #接收文件data = sc.recv(1024)file += dataget = 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+=1else: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 = 0total = 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()
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输相关推荐
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- Python学习笔记|二.Python安装教程
Python 安装教程 Python是跨平台的,它可以运行在Windows.Mac和各种Linux/Unix系统上.在Windows上写Python程序,放到Linux上也是能够运行的. 安装Pyth ...
- python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法
python3.4学习笔记(二十一) python实现指定字符串补全空格.前面填充0的方法 Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0. zfill()方法语法: ...
- python学习笔记(二) 基本运算
python学习笔记(二) 基本运算 1. 条件运算 基本语法 if condition1: do somethings1elif condition2: do somethings2else: do ...
- (Python入门)学习笔记二,Python学习路线图
(Python入门)学习笔记二,Python学习路线图 千里之行始于足下,谋定而后动,冰冻三尺非一日之寒.之所以说这三句话,就是对于下面整理的路线图,即不让自己感觉路途的遥远而感到达到巅峰神界的遥遥无 ...
- wxpython应用程序对象与顶级窗口_wxPython学习笔记(二)
如何创建和使用一个应用程序对象? 任何wxPython应用程序都需要一个应用程序对象.这个应用程序对象必须是类wx.App或其定制的子类的一个实例.应用程序对象的主要目的是管理幕后的主事件循环. 父类 ...
- Netty学习笔记二网络编程
Netty学习笔记二 二. 网络编程 1. 阻塞模式 阻塞主要表现为: 连接时阻塞 读取数据时阻塞 缺点: 阻塞单线程在没有连接时会阻塞等待连接的到达,连接到了以后,要进行读取数据,如果没有数据,还要 ...
- python编程语言继承_python应用:学习笔记(Python继承)
学习笔记(Python继承)Python是一种解释型脚本语言,可以应用于以下领域: web 和 Internet开发 科学计算和统计 人工智能 教育 桌面界面开发 后端开发 网络爬虫 有几种叫法(父类 ...
- pythonsze_python学习笔记二 数据类型(基础篇)
Python基础 对于Python,一切事物都是对象,对象基于类创建 不同类型的类可以创造出字符串,数字,列表这样的对象,比如"koka".24.['北京', '上海', '深圳' ...
最新文章
- btc比特币 钱包简介
- Java中的中介器设计模式
- hdu1394 Minimum Inversion Number 线段树和树状数组
- JS键盘事件(非常详细)
- [资源分享] 推荐两本电子书
- 限制MySQL Binlog的传输速率
- 动态游标for循环_【【动图算法】(动态规划篇):最长回文子串
- PHPExcel导出excel 复制代码
- spock做post请求get请求,在springboot环境下使用gradle构建工具的demo,IDEA的开发工具
- 油猴安装使用[自留]
- matlab计算遥感影像最“佳”指数因子OIF
- python 水位_python opencv之分水岭算法示例
- python列表比大小_Python列表按组大小排序
- 游戏平台系统源码有多重要?
- 图画日记怎么画_小学生绘画日记
- Axure RP 9 培训讲解---高级免费课程
- 图像边缘检测新方向--量子算法
- 【应届生租房】应届生如何租房以及注意事项
- 【小万出生记——第3篇】小万升级为家用服务机器人
- 使用windows Server 2003搭建DHCP服务器
热门文章
- 2021年饶州中学高考成绩查询,2021年鄱阳县高考状元名单资料,今年鄱阳县高考状元多少分...
- 配置QQ企业邮箱小结
- android studio编写java项目,并部署到Tomcat服务器
- vc windows服务程序调试
- 三维综合网格化智慧排水系统
- html里显示中文乱码的原因及解决办法
- 从零实现 USB_SLAVE读卡器 USB_MSC+FATFS+SD/SPI_FLASH/NANDFLASH
- 3D建模需要学多久可以学会?
- linpus linux 换win7,联想 lenovoIdeaPad可以装windows7系统吗_联想 lenovoIdeaPad怎么安装win7系统-win7之家...
- win7怎么看计算机端口,win7查看端口占用方法_win7怎么查看电脑端口占用-win7之家...