【问题标题】:tcp: why only second call to Socket.Receive(byte[]) returns data?tcp:为什么只有第二次调用 Socket.Receive(byte[]) 返回数据?
【发布时间】:2012-03-28 02:14:36
【问题描述】:

我有典型的情况。我需要通过 tcp 向服务器发送“请求”并接收响应。

// socket is connected
socket.Send(CreateRequest());
byte[] br = new byte[VERY_BIG_BUFFER];
int count = socket.Receive(br);   // only 4 bytes received: 15 0 0 0
count = socket.Receive(br);       // here I receive data I actually need

但是由于某种原因,我必须拨打socket.Receive 两次才能使一切正常。 在额外的通话中,我只收到四个字节:15 0 0 0。

在不了解我为什么需要它的情况下硬编码一个额外的调用可能会导致奇怪的问题。有人知道发生了什么以及为什么我需要额外的电话吗?

【问题讨论】:

    标签: .net sockets tcp


    【解决方案1】:

    TCP 是基于流的协议。它没有消息的概念。它只是一个字节序列。

    这意味着它可以将一个send 调用拆分为多个receive 调用,也可以将多个send 调用合并为一个receive 调用,或两者的组合。

    您需要以某种方式分隔您的消息。长度前缀是二进制协议的流行选择。

    【讨论】:

    • 我在第一次接收时看到我收到我应该收到 15 个字节。在第二次接收时,我收到这 15 个字节。但是我应该如何编码呢?只是先丢弃 Receive 不好,对吧?我是否应该循环接收数据,直到我收到前 4 个字节的数据量?
    • 另一个问题 - 如果 tcp 是字节序列 - 为什么第一个 socket.Receive 在 4 个字节后关闭,为什么我不需要重新连接来调用第二个 socket.Receive
    • “我是否应该在循环中接收数据,直到我收到前 4 个字节的数据量”是的,这就是要走的路。 |在 TCP 中,receive 可以随时返回比请求更少的字节。例如,因为许多字节已经到达,而其余的仍在传输中。然后你可以再次调用它来接收更多。 receive 返回0 表示流结束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 2020-04-13
    • 2013-04-08
    • 1970-01-01
    相关资源
    最近更新 更多