0

I am trying to code a kind of video chat room, like video conference call. I'm trying to do this with UDP, so that I won't have much lags. However, I can't send large enough sizes, even though I'm using all pickle, json and struct to make the size smaller.

The error I get:

socket.error: [Errno 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself

How can I make my code work (any ideas would be great, just how to make a conference video call with the less amount of lags possible).

Thanks in advance!

EDIT: I already have a text chatroom in UDP, what I'm trying to do now is extend it to also be voice chat room and video chat room. I have problems in the video, as I mentioned! Thanks!

Code:

Server:

__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"

Client:

__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)

By the way, the basis of that code is not mine, i found it on the internet and changed it to my needs. Basically, the server streams the data to all of the clients every times he recieves data from one of them. Thanks for any help!

idkidkidk
  • 159
  • 1
  • 1
  • 7
  • Welcome to stack, we will need to see the code where the issue is believed to be occurring, see [MVCE](https://stackoverflow.com/help/mcve). I also see you have posted another question about this topic. This question might be a duplicate to the first. Unless you can explain how this one differs. https://stackoverflow.com/questions/48856622/python-udp-multi-threaded-chat-room – Zack Tarr Feb 19 '18 at 13:45
  • Hello, it is not the same at all. The first was about how to make a chatroom work. I already made it work. This one is about sending large sized packets in UDP. This is connected to the first question because it is in the same project, but this is not at all the same. I will add the code soon, thank you. – idkidkidk Feb 19 '18 at 13:53
  • 1
    I have added the code – idkidkidk Feb 19 '18 at 14:45
  • Can anyone please help me with that? – idkidkidk Feb 19 '18 at 22:44

0 Answers0