如果出现[WinError 10040] 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。请将发送端的19行20行(//2)改大,或者将29行quality=50改小
- import socket
- import time
- import win32api, win32con
- from PIL import ImageGrab
- from io import BytesIO
-
-
- # 发送方
- def Sender():
- group_ip = '239.0.0.1'
- group_port = 10000
- # 创建IPv4/UDP套接字
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- # 获取当前分辨率下的屏幕尺寸
- width = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
- height = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
- # 压缩时,大小变为一半
- w = width // 2
- h = height // 2
- while True:
- # 截屏 bbox=None表示截取全屏
- # img = ImageGrab.grab(bbox=None)
- img = ImageGrab.grab(bbox=(0, 0, width, height))
- img.thumbnail((w, h))
- # 图像压缩
- output_buffer = BytesIO() # 建立二进制对象,在内存中读写
- # RGB格式压缩为JPEG格 式,quality: 保存图像的质量,1(最差)~100
- img.save(output_buffer, format='JPEG', quality=50)
- frame = output_buffer.getvalue() # 获取二进制数据
- # 发送文件
- sock.sendto(frame, (group_ip, group_port))
- time.sleep(0.05) # 加点延时更稳定。
-
-
- if __name__ == "__main__":
- Sender()
- import socket
- import struct
- import matplotlib.pyplot as plt
- import matplotlib.image as image
- from io import BytesIO
-
-
- # 接收方
- def Receiver():
- group_ip = '239.0.0.1' # 组地址
- group_port = 10000 # 端口号
- # 创建IPv4/UDP套接字
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- # 获取本地ip 先获取主机名,在通过主机名获取ip
- local_ip = socket.gethostbyname(socket.gethostname())
- # 绑定端口
- sock.bind((local_ip, group_port))
- # socket.inet_aton ip转为二进制
- # socket.INADDR_ANY 所有地址
- mreq = struct.pack("=4sl", socket.inet_aton(group_ip), socket.INADDR_ANY)
- # 加入组播组
- # 使用默认的IPV4组播接口
- sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
- while True:
- plt.clf() # 清除上一幅图像
- data, addr = sock.recvfrom(65536) # 接受数值大一点,防止被撑爆
- img = BytesIO(data)
- img = image.imread(img, format='jpeg')
- plt.imshow(img)
- plt.pause(0.05) # 暂停0.05秒 这一句是实现动态更新的
- plt.ioff() # 关闭画图的窗口
-
-
- if __name__ == '__main__':
- Receiver()
演示:
简易屏幕共享演示
屏幕共享程序解说视频