【问题标题】:Reading from data TcpClient inferior to socket从数据读取 TcpClient 不如套接字
【发布时间】:2012-06-26 14:59:45
【问题描述】:

我一直认为 TcpClient 会简化我的网络应用程序中的套接字操作。

但是,TcpClient 似乎需要知道应该从底层套接字读取多少数据。看起来 TcpClient.GetStream(..).Read(..) 调用 Socket.Receive(..) 读取指定的字节数。

TcpClient 公开了一个 NetworkStream,处理起来可能很烦人。诸如终止字符串和不可靠的 DataAvailable 属性之类的东西使未知 TCP“数据包”的读取变得复杂。

使用 Socket.ReceiveFrom(..) 似乎更面向“数据包”。

我通常使用TcpClient进行绑定和握手等,阅读我使用

        Socket socket = _tcpClient.Client;

        byte[] buffer = new byte[1000];

        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        EndPoint senderRemote = sender;

        int length = socket.ReceiveFrom(buffer, ref senderRemote);

        string replyString = Encoding.ASCII.GetString(buffer, 0, length);

        return replyString;

缓冲区初始化有一些开销,但它比从网络流中一次读取一个字节并查找终止字符或字符串要好。

TcpClient 没有以更好的方式处理读取数据,即 Socket 的方式,是不是有点奇怪?

【问题讨论】:

  • TCP 套接字是数据流,它们不是“基于数据包的”。一端可能会发送一个 32Kb 长的“数据包”,但当它通过 15 个不同的互联网服务器时,1 个数据包现在是 15 个单独的“数据包”,可能需要您调用 15 次接收。如果您没有看到这种行为,那么您还没有进行足够的真实世界测试。
  • @Neil 好吧,这个问题与 TcpClient 而不是 TCP 套接字有关。
  • TcpClient 只是 Socket 的一个包装器,带有一些辅助方法和属性。如果你想使用 Socket,那么没有什么能阻止你(TcpClient.Socket)。 IMO 将 TcpSocket 归咎于“怪异”是误解了 TCP 的实际工作原理。
  • @Neil 我不相信我在责备任何事情或任何人,或者声称 TCP 套接字是基于流的。

标签: c# .net


【解决方案1】:

有些协议有一个固定大小的标头,其中包含有效负载的大小,所以也许这并不奇怪。

在您的情况下,您最好直接使用Sockets,或者您可以在NetworkStream 周围编写一个包装器,该包装器会读入缓冲区并允许您将Peek() 放入其中以获取终止字符。

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多