【问题标题】:How can I Receive a Large Data Stream through a Socket Connection - without TCPClient如何通过套接字连接接收大数据流 - 没有 TCPClient
【发布时间】:2016-08-25 14:40:03
【问题描述】:

我有一个问题,我想通过 SocketConnection 发送一个大字符串,但由于网络限制为 1500 个字节,我无法立即接收该字符串,所以我如何才能通过 Socket 接收所有字节而不使用 TCPClient,或者那是不可能的。

    public string ReceiveString(Socket connection)
    {
        byte[] buffer = new byte[1048576];
        int recBytes = connection.Receive(buffer);
        return UnicodeEncoding.Unicode.GetString(buffer, 0, recBytes);
    }

这就是我目前所拥有的。

如果不可能,要通过 Socket 获取它,我可以从 Socket 中获取 EndPoint 以使用 TCPClient 作为“最后一个选项”吗?

【问题讨论】:

  • 您必须自己实现protocol level 才能将数据拆分为数据包并接收(连接)它们。
  • 你不能。 TCP 将每条消息分解为大约 1500 字节的数据报。当您应该使用异步方法时,您正在使用同步 Receive() 方法。您需要在发送函数中添加一个终止字符,以便接收函数可以继续读取 1500 个数据报,直到找到结束字符。
  • 我的意思是,TCP 不是有某种结束序列吗,我听说了一些关于 \0 的事情?
  • @Silent3241 不,它没有。 TCP 根本没有消息的概念。 TCP 之上的更高级别的应用程序定义协议实现消息帧。
  • @jdweng 切换到异步读取并不能解决问题。同步阅读就可以了。解决方案是将字符串框起来,以便读者知道何时停止阅读。要么 1) 在发送字符串之前发送字符串长度,要么 2) 使用不能出现在字符串中的唯一分隔符终止字符串。

标签: c# sockets


【解决方案1】:

TCP 是一个字节流,它没有消息的概念。线路上单个数据包的大小无关紧要,它只是网络硬件的一个实现细节。 TCP 保证您发送的内容就是您收到的内容(但在单个发送的大小和单个读取的大小之间没有一对一的关系,就像在 UDP 中那样)。

该解决方案要求发送者以允许阅读者知道何时停止阅读的方式对字符串数据进行构图。要么:

  1. 在发送字符串数据之前发送字符串长度。然后阅读器可以先读取长度,然后读取指定数量的后续字节。

  2. 一个。使用不能出现在字符串本身中的唯一分隔符终止字符串。然后阅读器可以继续阅读,直到遇到分隔符。

    b.分隔符可以关闭连接。阅读器可以继续阅读,直到检测到断开连接。

您需要使用哪种解决方案取决于您正在实施的特定协议。 #1 最适合二进制协议,并允许有效的内存管理,而 #2 更适合基于文本的协议,或最终长度无法提前知道的流协议。有时,当 #1 和 #2a 不可行时,协议不得不求助于 #2b(HTTP 和 FTP 都使用它)。

【讨论】:

  • 或者切换到构建在 TCP 之上的更高级别的协议,该协议为您实现消息传递/框架。
  • @Damien_The_Unbeliever 您可能更多地考虑预制库而不是协议。如果您只是设计/采用消息传递协议,您仍然需要实现用于发送和读取消息帧的代码。
  • 嗯,我在考虑“切换到 HTTP”或类似的东西。 IE。一种建立在 TCP 之上的协议,它已经有了消息传递的概念。
  • @Damien_The_Unbeliever 这并没有真正改变我所说的话。如果您手动实现 HTTP(或其他),则必须自己编写消息传递逻辑(并且 HTTP 实际上利用了我在回答中提到的 所有三个 框架场景),除非您使用处理消息传递的预制库为您提供详细信息。
  • 好的,我认为这只是一个措辞。我的意思是“切换到更高级别的协议使用该协议的预制实现”。
猜你喜欢
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2018-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 2022-01-01
相关资源
最近更新 更多