客户端
import socket
import threading
import cv2
import numpy as np
# 接收数据
def recv():
img_bytes = b'' # 保存一张图像
while True:
try:
data = client.recv(1024)
if data: # 判断data不为空
if data == begin_flag: # 如果是起始包来了
while True: # 开启一个循环接受数据
data = client.recv(1024)
if data[-(len(end_flag)):] == end_flag: # 如果包包含结束标志 表示结束包 则说明一张图像数据完毕
img_bytes = img_bytes + data[0:(len(data)-len(end_flag))] # 记得去掉结束标志的数据
break # 跳出接收这样图像的循环
img_bytes = img_bytes + data # 如果不是结束包 则将数据添加到变量 继续循环
# print(img_bytes)
#显示图片
np_data = np.frombuffer(img_bytes, dtype="uint8")
r_img = cv2.imdecode(np_data, cv2.IMREAD_COLOR)
r_img = r_img.reshape(pic_height, pic_width, 3)
cv2.imshow("title", r_img)
img_bytes = b''
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
client.close()
print("Connect Fail!")
break
cv2.destroyAllWindows()
pic_width = 800 # 定义接受图像的大小
pic_height = 600
begin_flag = b'Framebegin:' # 接受包的起始标志
end_flag = b'Frameovers:' # 接受包的结束标志
client = socket.socket()
addr = ("121.4.99.98", 8080)
try:
client.connect(addr)
client.send("Hello Server!\n".encode()) # 往服务器发送一条数据
t0 = threading.Thread(target=recv) # 开启接受数据线程
t0.start()
except Exception as e:
print("Connect to server Fail!")
服务器端
import threading
import time
import cv2
import numpy as np
import pyautogui
import socket
def send_pic(client):
# 起始坐标 0 0 截取一张 640宽 400 高的图像 类型PIL.Image.Image image mode=RGB
pil_im = pyautogui.screenshot(region=(0, 0, pic_width, pic_height))
np_img = cv2.cvtColor(np.asarray(pil_im), cv2.COLOR_RGB2BGR) # 将PIL.Image.Image 转换为 numpy.ndarray 类型的数组 可以 使用cv2.imshow('a', np_img)显示
res, send_data_num = cv2.imencode('.jpg', np_img, (cv2.IMWRITE_JPEG_QUALITY, 50)) # 将图片编码
send_data = send_data_num.tobytes() #编码转换为 字节流
send_data_len = len(send_data) # 获取数据长度
# print(send_data)
i = send_data_len // package_len # 分包发送 包的个数
j = send_data_len % package_len # 剩余字节的个数
client.send(begin_flag) # 发送起始标志
for n in range(0, i): # 分包发送
client.send(send_data[n * package_len:package_len * (n + 1)])
client.send(send_data[-j:]) # 发送剩余字节
client.send(end_flag) # 发送结束标志
# 接收数据线程
def recv(client, client_addr):
while True:
try:
data = client.recv(1024)
if data:
print(data)
except Exception as e:
if client in client_addr:
client.close()
client_arr.remove(client)
# 发送图像的线程
def send():
while True:
for c in client_arr:
try:
send_pic(c) # 发送图像
except Exception as e:
if c in client_arr:
c.close()
client_arr.remove(c)
# time.sleep(10)
pic_width = 800
pic_height = 600
begin_flag = b'Framebegin:' # 一张图像起始标志
end_flag = b'Frameovers:' # 一张图片结束标志
package_len = 1024 # 一帧数据长度
ser = socket.socket()
addr = ("10.0.4.11", 8080)
ser.bind(addr)
ser.listen(5)
client_arr = [] # 保存客户端
t0 = threading.Thread(target=send)
t0.start()
while True:
client, client_addr = ser.accept()
client_arr.append(client)
print(f"client {client_addr} connected!")
t1 = threading.Thread(target=recv, args=(client, client_addr))
t1.start()