i am trying to send frames over socket and after encoding they are usualy 50 000 - 80 000 bytes so i am reciving data by loop but since client is sending frames always the loop in the code bellow wont break so when i run nothing happens and the reciving loop keep going
Client
import socket
import cv2
import time
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
s.connect(("127.0.0.1",60124))
camera = cv2.VideoCapture(0)
while True :
r , f = camera.read()
f = cv2.imencode(".jpg",f)[1].tostring()
s.sendall(f)
Server
import socket
import numpy as np
import cv2
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
s.bind(("127.0.0.1",60124))
s.listen(5)
c , a = s.accept()
while True :
data = ""
while True:
f = c.recv(1024)
if not f :
break
data += f
x = np.fromstring(data , np.uint8)
var = cv2.imdecode(x , cv2.IMREAD_COLOR)
cv2.imshow("Camera" , var)
cv2.waitKey(1)
Helpp plss
I suggest you to send the length first, and then the data.
When the server receive the "payload" length, it knows how many data bytes expect.
The client:
len(f)
as 8
bytesf
The server:
8
bytes to get len_f
.len_f
of data bytes.In my example, len_f
is encoded as base64
format.
The number of bytes for sending len_f
is always 8 bytes (due to base64 automatic padding).
You may encode the data
as base64
as well.
It's important if you are sending the data through HTTP.
I put the base64
encoding/decoding of the image data in comment.
Only the length is encoded as base64
(you may alternatively send the length as text format).
Client:
import socket
import numpy as np
import cv2
import base64
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
s.connect(("127.0.0.1", 60124))
width, height, n_frames = 640, 480, 100 # 100 frames, resolution 640x480
for i in range(n_frames):
# Generate synthetic image:
img = np.full((height, width, 3), 60, np.uint8)
cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20) # Green number
# JPEG Encode img into f
_, f = cv2.imencode('.JPEG', img)
# Encode jpeg_img to base64 format
#f = base64.b64encode(f)
# Get length of f and encode to base64
#f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))
f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))
# Send the length first - so the server knows how many bytes to expect.
s.sendall(f_len) # Send 8 bytes (assumption: b64encode of 4 bytes will be 8 bytes due to the automatic padding feature).
s.sendall(f)
s.close()
Server:
import socket
import numpy as np
import cv2
import base64
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 60124))
s.listen(5)
c, a = s.accept()
while True:
# Read 8 bytes that tells the length of encoded image to be expected.
data = c.recv(8)
if len(data) != 8:
break
# Decode f_len from base64
f_len = base64.decodebytes(data)
# Convet from array of 4 bytes to integer value.
f_len = int.from_bytes(f_len, byteorder='little')
#f = c.recv(1024)
# Receive the encoded image.
data = c.recv(f_len)
if len(data) != f_len:
break
#x = base64.decodebytes(data) # Decode base64
#x = np.fromstring(x , np.uint8)
x = np.fromstring(data, np.uint8)
var = cv2.imdecode(x, cv2.IMREAD_COLOR)
if var is None:
print('Invalid image')
else:
cv2.imshow("Camera" , var)
cv2.waitKey(100)
s.close()
cv2.destroyAllWindows()