How to make tcpClient not receive multiple message per each conn.sendall()?
Question:
Python server sender side:
soc = socket.socket()
hostname="localhost"
port=8000
soc.bind((hostname,port))
soc.listen(1)
conn , addr = soc.accept()
print("device connected")
cc = 0
cap = cv2.VideoCapture(0)
with mp_hollistic.Holistic(static_image_mode = True ,min_detection_confidence=0.7, min_tracking_confidence=0.7) as holistic:
while cap.isOpened():
ret, frame = cap.read()
res, f = func(frame)
val = '0,0'
if(res is not None):
val = str(round(res[0],3)) +',' + str(round(res[1],3))
print(val)
conn.sendall(val.encode('utf-8'))
#time.sleep(1)
cv2.imshow('OpenCV Feed', f)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
C# client receiver side:
void tt_Tick(object sender, EventArgs e)
{
NetworkStream DataStream = client.GetStream(); //Gets the data stream
byte[] buffer = new byte[client.ReceiveBufferSize]; //Gets required buffer size
int Data = DataStream.Read(buffer, 0, client.ReceiveBufferSize); //Gets message (encoded)
string message = Encoding.UTF8.GetString(buffer, 0, Data);
DrawDubble(CreateGraphics());
}
on the client side . I expect a single message to get coordinates (11,16) but rather than that the message carriers multiple messages like (35,12),(12,31),(11,16)
How do I make the client side receive a single message per each conn.sendall?
Answers:
How do I make the client side receive a single message per each conn.sendall?
You don’t. You’re using a stream-based protocol (TCP): you get a stream of bytes, and that’s all. The various network layers can combine multiple messages into a single packet, or split a single message into multiple packets. (And calling Read
isn’t guaranteed to read the data from exactly one packet either.)
If you need to break that stream up into messages, you need to put a protocol on top of TCP, e.g. by putting the length of the message before the message data, or by using a delimiter between messages. For example, if your stream of data is all text (as it looks like it is) and if you never need line breaks within your messages you could potentially make it a line-based protocol: open a StreamReader
wrapping the NetworkStream
, and just call ReadLine
in a loop.
Alternatively, use UDP where as far as I’m aware you really will get a single packet at a time – but which comes with reliability constraints.
Python server sender side:
soc = socket.socket()
hostname="localhost"
port=8000
soc.bind((hostname,port))
soc.listen(1)
conn , addr = soc.accept()
print("device connected")
cc = 0
cap = cv2.VideoCapture(0)
with mp_hollistic.Holistic(static_image_mode = True ,min_detection_confidence=0.7, min_tracking_confidence=0.7) as holistic:
while cap.isOpened():
ret, frame = cap.read()
res, f = func(frame)
val = '0,0'
if(res is not None):
val = str(round(res[0],3)) +',' + str(round(res[1],3))
print(val)
conn.sendall(val.encode('utf-8'))
#time.sleep(1)
cv2.imshow('OpenCV Feed', f)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
C# client receiver side:
void tt_Tick(object sender, EventArgs e)
{
NetworkStream DataStream = client.GetStream(); //Gets the data stream
byte[] buffer = new byte[client.ReceiveBufferSize]; //Gets required buffer size
int Data = DataStream.Read(buffer, 0, client.ReceiveBufferSize); //Gets message (encoded)
string message = Encoding.UTF8.GetString(buffer, 0, Data);
DrawDubble(CreateGraphics());
}
on the client side . I expect a single message to get coordinates (11,16) but rather than that the message carriers multiple messages like (35,12),(12,31),(11,16)
How do I make the client side receive a single message per each conn.sendall?
How do I make the client side receive a single message per each conn.sendall?
You don’t. You’re using a stream-based protocol (TCP): you get a stream of bytes, and that’s all. The various network layers can combine multiple messages into a single packet, or split a single message into multiple packets. (And calling Read
isn’t guaranteed to read the data from exactly one packet either.)
If you need to break that stream up into messages, you need to put a protocol on top of TCP, e.g. by putting the length of the message before the message data, or by using a delimiter between messages. For example, if your stream of data is all text (as it looks like it is) and if you never need line breaks within your messages you could potentially make it a line-based protocol: open a StreamReader
wrapping the NetworkStream
, and just call ReadLine
in a loop.
Alternatively, use UDP where as far as I’m aware you really will get a single packet at a time – but which comes with reliability constraints.