我正在尝试编写一种视频聊天室,例如视频会议电话。 我试图用UDP做到这一点,所以我不会有太多的滞后。 但是,即使我使用所有pickle,json和struct来缩小尺寸,我也无法发送足够大的尺寸。
我得到的错误:
socket.error:[Errno 10040]在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或用于接收数据报的缓冲区小于数据报本身
如何让我的代码工作(任何想法都会很棒,如何以较少的滞后量进行会议视频通话)。
提前致谢!
编辑: 我已经在UDP中有一个文本聊天室,我现在要做的就是将它扩展为语音聊天室和视频聊天室。正如我所提到的,我在视频中遇到了问题! 谢谢!
代码:
服务器:
__author__ = 'user'
import socket
import time
import sys
import json
import pickle
import numpy as np
import struct
UDP_IP = sys.argv[1]
UDP_PORT = int(sys.argv[2])
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP,UDP_PORT))
clients = []
def broadcast(data):
global clients
for client in clients:
sock.sendto(data, client[1])
while True:
data = None
message = None
try:
sock.settimeout(0.01)
data, addr = sock.recvfrom(1024)
message = json.loads(data)
client = (message['username'], addr)
if client not in clients:
clients.append(client)
except socket.error:
time.sleep(0.01)
if data:
print data
try:
if (message['message'].startswith("/hello")):
to_send = {"username" : "server", "message" : message['username'] + " joined the chat"}
to_send_final = json.dumps(to_send)
broadcast(to_send_final)
elif (message['message'].startswith("/who")):
to_send = {"username" : "server","message" : "people in room: " + ', '.join([y[0] for y in clients])}
to_send_final = json.dumps(to_send)
sock.sendto(to_send_final, client[1])
elif (message['message'].startswith("/goodbye")):
to_send = {"username" : "server", "message" : message['username'] + " left the chat"}
to_send_final = json.dumps(to_send)
clients.remove(client)
broadcast(to_send_final)
else:
to_send = {"username" : message['username'],"message" : message['message']}
to_send_final = json.dumps(to_send)
broadcast(to_send_final)
print clients
except:
print "an error has occured"
客户端:
__author__ = 'user'
import socket
import sys
import thread
import time
import json
import cv2
import numpy as np
import pickle
import struct
server_ip = sys.argv[1]
server_port = sys.argv[2]
username = sys.argv[3]
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cap=cv2.VideoCapture(0)
def get_messages():
global sock, username
data_2 = ""
payload_size = struct.calcsize("L")
while True:
while len(data) < payload_size:
data += sock.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 += sock.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data)
print frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
def get_input():
global sock, username
try:
while True:
ret,frame=cap.read()
vid_message = pickle.dumps(frame)
message = { "username" : username, "message" : vid_message }
final_message = json.dumps(message)
last_message = struct.pack("L", len(final_message))+final_message
sock.sendto(last_message, (server_ip, int(server_port)))
except KeyboardInterrupt:
print "byebye now"
thread.start_new_thread(get_input, ())
thread.start_new_thread(get_messages, ())
message = {"username" : username, "message" : "/hello"}
sock.sendto(json.dumps(message), (server_ip, int(server_port)))
message = {"username" : username, "message" : "/who"}
sock.sendto(json.dumps(message), (server_ip, int(server_port)))
try:
while 1:
time.sleep(0.01)
except KeyboardInterrupt:
print "bye"
message = {"username" : username, "message" : "/goodbye"}
sock.sendto(json.dumps(message), (server_ip, int(server_port)))
sock.close()
cap.release()
cv2.destroyAllWindows()
sys.exit(0)
顺便说一句,该代码的基础不是我的,我在互联网上找到它并根据我的需要改变它。 基本上,服务器每次从其中一个客户收到数据时都会将数据流式传输到所有客户端。 谢谢你的帮助!