英文:
How to make tcpClient not receive multiple message per each conn.sendall()?
问题
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()
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[] messages = Encoding.UTF8.GetString(buffer, 0, Data).Split(',');
foreach (var message in messages)
{
DrawDubble(CreateGraphics());
}
}
英文:
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?
答案1
得分: 2
你不需要。你正在使用基于流的协议(TCP):你会得到一串字节流,仅此而已。各种网络层可以将多个消息组合成一个数据包,或将单个消息拆分为多个数据包。(而且调用 Read
也不能保证从一个数据包中完全读取数据。)
如果你需要将该流拆分成消息,你需要在TCP之上添加一个协议,例如在消息数据之前放置消息长度,或者在消息之间使用分隔符。例如,如果你的数据流全是文本(看起来是这样),而且消息中永远不需要换行,你可以潜在地将其制作为基于行的协议:打开一个包装了 NetworkStream
的 StreamReader
,然后在循环中调用 ReadLine
。
或者,使用UDP,据我所知,你确实会一次收到一个数据包,但这会伴随着可靠性约束。
英文:
> 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论