Pickle data was truncated (desktop streaming) - python

I'm trying to build a desktop streaming app. It consists of a server and a client for now. I learned that I should use the library pickle in order to serialize/deserialize the data. However, when I run both the scripts, I get the error "Pickle data was truncated" from the client side. Could you help me to solve this? I tried the solution the following link, whose OP apparently was trying to do the similar think but it didn't work.
python 3.6 socket pickle data was truncated
Server
import numpy as np
import cv2
from PIL import ImageGrab
import socket
import pickle
HOST = "0.0.0.0"
SOCKET = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST,SOCKET))
while True:
s.listen(5)
client, addres = s.accept()
print(addres, " has connected")
img = ImageGrab.grab()
img_np = np.array(img)
img_np_serial = pickle.dumps(img_np)
client.send(img_np_serial)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
Client
import socket
import pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostbyname(socket.gethostname()),5000))
data = b""
while True:
packet = s.recv(4096)
if not packet: break
data += packet
data_deserial = pickle.loads(data)
print((data_deserial))

Related

error when sending video feed bytes using socket

I am using sockets to send video feed bytes from server to client. The video feed is being captured using openCV. But the method I am using right now works for a couple of seconds and stops with error OSError: [WinError 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 Where did I go wrong and how can I fix it? Thanks in advance.
HOST
import cv2
import socket
import pickle
s_stream = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s_stream.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 10000000)
streamIp = "192.168.3.5"
streamPort = 8787
camera = cv2.VideoCapture(0)
while True:
ret, img = camera.read()
ret, buffer = cv2.imencode(
'.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 30])
x_as_bytes = pickle.dumps(buffer)
s_stream.sendto(x_as_bytes, (streamIp, streamPort))
CLIENT
import cv2, socket, pickle
s_stream=socket.socket(socket.AF_INET , socket.SOCK_DGRAM)
streamIp="192.168.3.5"
streamPort=8787
s_stream.bind((streamIp,streamPort))
while True:
x=s_stream.recvfrom(10000000)
clientip = x[1][0]
data=x[0]
data=pickle.loads(data)
print(data)

why only the first timeframe of streamed video over Kafka served in a simple HTTP Server?

I tried to stream a video over Kafka and displaying it in a simple HTTP server, built in Python. regardless the good streaming data, only the first timeframe (or first received timeframe) is served in the HTTP Server.
I have proved that the sent and received timeframes equal to the streamed video (by exporting out the sent and received time frames). my suspicion is that the HTTP Server doesn't automatically refresh or write the received timeframe every new messages are received.
KafkaProducer
import cv2
import io
from PIL import Image
from kafka import KafkaProducer
def recordedVid(video_file):
producer = KafkaProducer(
bootstrap_servers='localhost:9092'
)
cap = cv2.VideoCapture(video_file)
while(cap.isOpened()):
ret, frame = cap.read()
ret, buffer = cv2.imencode('.jpg', frame)
toStream = buffer.tobytes()
producer.send('Video', toStream)
print('sent')
time.sleep(0.1)
cap.release()
print('done')
recordedVid('sample.mp4')
KafkaConsumer
import cv2
import socket
from http.server import HTTPServer, BaseHTTPRequestHandler
from kafka import KafkaConsumer
from PIL import Image
import numpy as np
import io
from ensurepip import bootstrap
def extract_IP():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
HOST = s.getsockname()[0]
return HOST
def msg_process(msg) :
frame_bytes = msg.value
frame_arr = np.frombuffer(frame_bytes, np.uint8)
frame = cv2.imdecode(frame_arr, cv2.IMREAD_COLOR)
img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
toLoad = io.BytesIO()
img.save(toLoad, format='JPEG')
return toLoad.getvalue()
consumer = KafkaConsumer(
"Video",
bootstrap_servers = 'localhost:9092'
)
class Display(BaseHTTPRequestHandler):
def do_GET(self):
for msg in consumer:
frame = msg_process(msg)
self.send_response(200)
self.send_header("Content-type", "image/jpeg")
self.end_headers()
self.wfile.write(frame)
HOST = extract_IP()
PORT = 9999
server = HTTPServer((HOST, PORT), Display)
print("server is now running in ", HOST," and Port ", PORT)
server.serve_forever()
server.server_close()
Did I miss something or is there any workaround for my problem?

How and when to process the data received by socket client in python?

I have created a socket client in python that is meant to receive data from socket server (which is sending data to client at constant time interval) and construct an image out of the data by using cv2 and numpy. I have tested the Socket Client and Server for echo communication for text data and it is working as expected. The Socket Server is ESP32CAM Access Point and it is also working as expected. I am facing issue when I try to write the Socket Client python code, because as the ESP32CAM Socket Server is sending data at constant time interval, the Socket Client has to be ready to receive data at that exact moment, which is the issue I have. I would like to know whether there is some concept like Interrupts in python like microcontrollers.
Here is my python code :
import socket
import sys
import time
import io
import cv2
import numpy
import numpy as np
host = "192.168.4.1"
port = 80
print('# Creating socket')
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Failed to create socket')
sys.exit()
print('# Getting remote IP address')
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
print('Hostname could not be resolved. Exiting')
sys.exit()
print('# Connecting to server, ' + host + ' (' + remote_ip + ')')
sock.connect((remote_ip , port))
print('Server Connected !')
while True:
begin = time.time()
message_chunks = []
d = ''
while True:
if time.time() - begin > 0.2: #200 ms
break
try:
d = sock.recv(4194304) #4MB data
#print(d)
except socket.timeout:
break
if d:
message_chunks.append(d)
else:
break
data = b''.join(message_chunks)
img = io.BytesIO()
img.write(data)
img.seek(0)
imgnp = numpy.array(bytearray(img.read()), dtype=np.uint8)
frame = cv2.imdecode(imgnp,-1)
cv2.startWindowThread()
cv2.namedWindow("stream", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("stream",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
cv2.imshow("stream", frame)
I kindly request for some guidance in threading and parallel processing for this code as well.

webcam streaming using python

I'm having a idea of using TCP socket to send array object captured by webcam to a client and reconstruct the image in another program.
Server Side:
import socket
import numpy as np
import cv2
UDP_IP = '192.168.1.3'
UDP_PORT = 8081
cap = cv2.VideoCapture(0)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((UDP_IP,UDP_PORT))
sock.listen(1)
conn,addr=sock.accept()
print(addr)
while(True):
ret, frame = cap.read()
cv2.imshow('streamer',frame)
conn.send(frame.toBytes)
print(frame)
Client side:
import socket
import numpy
import time
import cv2
UDP_IP="192.168.1.3"
UDP_PORT = 8081
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((UDP_IP,UDP_PORT))
while True:
data = sock.recv(480*640*3)
print(data)
my issue is in server side the array is showing up correctly in the console. But in the client side the console is filled with Junk characters.
Why is that.? How should i reconstruct the array same as the server side?

sending images from client to server using socket python

I'm trying to send multiple images from client to server .
from my client I send one image at a time then for each image I get the size in the server and then send the size back to client and then try and store all the sizes of all images in a table .
I wrote this code and it doesn't seem to work:
client.py:
from PIL import Image
import glob
import sys
import pickle
import socket
import os
import numpy
reload(sys)
def readFileImages(strFolderName):
st = os.path.join(strFolderName, "*.png")
print st
return glob.glob(st)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client_socket.bind(("127.0.0.1", 4000))
list1=readFileImages("test")
myoutput =[]
while (list1):
for im in list1:
f=open(im,"rb")
while True:
veri = f.read()
if not veri:
break
client_socket.send(veri)
f.close()
data = client_socket.recv(4096)
data_arr=pickle.loads(data)
newrow=numpy.asarray(data_arr)
myoutput=numpy.vstack([myoutput,newrow])
client_socket.close()
numpy.savetxt("testTable.csv",myoutput,delimiter=",")
server.py:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
s.bind(("127.0.0.1",4000))
s.listen(5)
client_socket, address = s.accept()
print "Connected to - ",address,"\n"
fname="test.png"
fp = open(fname,'wb')
# image
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
#T[0]=detect_carte_grise(fp)
im = Image.open(fp)
T= im.size #width,height
data=pickle.dumps(T)
client_socket.send(data)
and why do i get this error ?:[errno98] address already in use
I cannot even connect to server
First, in server code you bind to port, but in client code, you need to CONNECT to that server. You are binding in both of your scripts and address is already used by the first running script. so in client drop bind and change to client_socket.connect(("127.0.0.1", 4000)). That will resolve current issues, if you have any more, please, ask another question.
I got the same error, I Changed the "port number". It's worked fine

Categories