如何使tcpClient在每个conn.sendall()调用时不接收多个消息?

huangapple go评论70阅读模式
英文:

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之上添加一个协议,例如在消息数据之前放置消息长度,或者在消息之间使用分隔符。例如,如果你的数据流全是文本(看起来是这样),而且消息中永远不需要换行,你可以潜在地将其制作为基于行的协议:打开一个包装了 NetworkStreamStreamReader,然后在循环中调用 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.

huangapple
  • 本文由 发表于 2023年3月8日 16:58:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671051.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定