目录
1、Python socket 文件传输
(1)发送单个文件(一次性)
(2)发送一个文件夹下的所有文件(一次性)
(3)发送每个文件夹下的最新文件(等时间间隔持续发送)
2、usb摄像头RTSP视频推流
(1)下载与配置
(2)使用
1、Python socket 文件传输
简介:python的socket库提供了基于TCP/IP协议的数据传输功能,相当于服务器端开了一个通道listen着,等待一台客户端connect,成功建立连接后,通过send和recv的发送和应答来实现数据传输
需要:同一内网下两台设备的ip地址(在cmd中,windows通过ipconfig命令查看,ubuntu通过ifconfig查看)
(1)发送单个文件(一次性)
参考博客:https://blog.csdn.net/m0_55415810/article/details/1214 p54582
(2)发送一个文件夹下的所有文件(一次性)
参考博客:python socket通信传输某文件夹下的所有图片_不告诉你/tp的博客-CSDN博客
这段代码我在运行试用的时候有出现报错。
一开始send一长串十六进制字符串,相当于是在对暗号,对上暗号了服务器才确认发送数据。但是我这里收发都报错,原代码 s.send("\xAA\x96\xAC\x00\x01\x00\x01\x69") 报错 TypeError: a bytes-like object is required, not 'str' ,改成了 s.send(b'\xAA\x96\xAC\x00\x01\x00\x01\x69') ;原代码 if(rev_str[6] == b"\x01") 的判断报错,应该是进制的问题,我改成了 if(str(rev_str[6]) == “1”) 用十进制判断就可以了
另外前面的send和recv,收发的是文件长度等信息,需要encode和decode成utf-8格式,否则也报错TypeError: a bytes-like object is required, not 'str'
(3)发送每个文件夹下的最新文件(等时间间隔持续发送)
前情提要:应用场景是有N个摄像头,对应N个文件夹,定时更新摄像头的最新抓拍截图,需要将最新的图像传输给其他客户端。
基于(2)进行了一些修改,尤其要注意沾包的问题,如果存在两次连续的send,而实际想要发送的这两次是两个独立的数据文件,对于socket来说他认为两次连续发送的内容是粘连在一起发送的。因此要避免连续的send,在send中间加一句recv(),进行阻塞,多一次一问一答的确认。
上代码:
(传输的数据存放方式与命名格式如下,可根据自己的需求自行修改)
服务器端-发送(先启动):
import sys
import socket
import time
import os
import re
s_server = socket.socket()
print("开始创建服务器socket")
host = ''
port = 7891 # 随意设置一个空闲的端口号(和客户端保持一致即可)
addr = (host, port)
s_server.bind(addr) # 绑定端口
s_server.listen(5) # 监听等待客户端的connect,没有的话就一直停留在这一步等待
# 客户端程序运行以后就成功建立了连接
to_client, addr = s_server.accept()
print ('...connected from :', addr)
rev_str = to_client.recv(1024)
print(rev_str)
# 确认过暗号,是要接受该客户端的信息
if(str(rev_str[6]) == "1"):
start = time.time()
while True:
# 每隔一定时间(20s)发送一次
if (time.time() - start) > 20:
# 遍历文件夹下的所有文件夹
path_folder = r"/home/ysj/parking/code/cameras/"
dirs_folder = os.listdir(path_folder)
print("文件夹个数")
print(len(dirs_folder))
to_client.send(str(len(dirs_folder)).encode('utf-8'))
# 遍历文件夹
for folder in dirs_folder:
# 函数阻塞,防止沾包(避免连续两个send)
to_client.recv(8)
start1 = time.time()
print("当前文件夹:%s"%folder)
# 获取该文件夹下的所有图片文件
path_file = path_folder + folder + "/"
files = os.listdir(path_file)
# 对文件夹内的图片按文件名中的序号排序,取最大的那张(最新)
# 我的图片命名格式如:192.168.1.104_15.jpg,需要用正则表达式取出其中的序号“15”
files.sort(key = lambda x:int(x[re.search('(?<=_)(.+?)(?=\.jpg)', x).span()[0] : re.search('(?<=_)(.+?)(?=\.jpg)', x).span()[1]]))
# 取最后一张图片
file_size = os.path.getsize(path_file + files[-1])
print('即将发送的文件长度是:%d '%file_size)
file_info='%s|%s'%(files[-1], file_size)
to_client.send(file_info.encode('utf-8'))
to_client.recv(6)
# 一张图片可能要分好几批才能发送完,此处是连续send
fout = open(path_file + files[-1], "rb")
has_send = 0
while has_send < file_size:
frame_data = fout.read(1024)
to_client.send(frame_data)
has_send+=len(frame_data)
end1 = time.time()
dur1 = end1 - start1
print('time cost: %.5f sec' %dur1)
start = time.time()
# 如果要定时持续接收的话就不关闭连接了
# print("program exit normally:-> close socket")
# s_server.close()
# to_client.close()
客户端-接收:
import socket # 导入 socket 模块
import time
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 7891 # 设置端口号
s.connect(("192.168.1.106", port)) # 服务器的ip地址
while True:
# 允许一轮接收发的时候才进行
# 都要encode和decode成utf-8,否则报错无法传输str而是需要字节
s.send(b'\xAA\x96\xAC\x00\x01\x00\x01\x69')
# 对上暗号后,接收即将传输的文件夹下的文件个数
file_num = s.recv(1024).decode('utf-8')
print(file_num)
file_num = int(file_num)
for file_end in range(0, file_num):
# 对应服务器端的那一句防止沾包的recv,传的内容无所谓
s.send(str(file_num).encode('utf-8'))
file_info = s.recv(80).decode('utf-8')
print(file_info)
filename,filesize=str(file_info).split('|')
s.send(filesize.encode('utf-8'))
filesize=int(filesize)
# 接收文件的位置
f_txt = open("./receive0905/"+filename, "ab")
has_receive = 0
while has_receive < filesize:
picture_date = s.recv(1024)
f_txt.write(picture_date)
has_receive+=len(picture_date)
# time.sleep(2)
f_txt.close()
print("接收了一个")
# s.close()
2、usb摄像头RTSP视频推流
参考博客:2.gstreamer USB摄像头RTSP推流_生如~夏花的博客-CSDN博客_gstreamer usb摄像头
(1)下载与配置
先下gst-rtsp-server,不能要最新版本的,没有autogen.sh,用旧版本
git clone -b 1.8 https://github.com/GStreamer/gst-rtsp-server.git
再下载common.git,粘贴到server下common文件夹下:
GitHub - GStreamer/common: 'common' shared submodule. This module is unused and deprecated.
然后就运行autogen.sh,make就好:
cd gst-rtsp-server
./autogen.sh
sudo make
(2)使用
使用的时候进入examples文件夹
注:device=/dev/video0,此处的序号0是接入的摄像头序号,如果有多个摄像头需要修改
查看摄像头设备
sudo v4l2-ctl --list-devices
./test-launch --gst-debug-level=3 "( v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, format=(string)NV12, width=640, height=480, framerate=30/1 ! queue ! x264enc bitrate=10240 ! rtph264pay name=pay0 pt=96 )"
(不记得最后成功执行的是哪一段代码了)
./test-launch --gst-debug=3 "( v4l2src ! video/x-raw,width=640,height=480, framerate=30/1 ! omxh264enc ! h264parse ! rtph264pay name=pay0 pt=96 )"
执行后显示:stream ready at rtsp://127.0.0.1:8554/test
在同一局域网下的另一台主机上,就可以在VLC plyaer里打开网络串流,地址改成服务器的ip地址即可
或者通过opencv也可以获取
问题:当前的视频推流延迟太高了,有10s左右,还未深究
主要参考:
python socket通信传输某文件夹下的所有图片_不告诉你/tp的博客-CSDN博客
2.gstreamer USB摄像头RTSP推流_生如~夏花的博客-CSDN博客_usb摄像头rtsp推流
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)