2011-01-05 118 views
3

有没有一种方法可以确定C#中TCPIP套接字的接收缓冲区大小。我正在向服务器发送一条消息,并期望在不确定接收缓冲区大小的情况下做出响应。套接字接收缓冲区大小

  IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.125.125.226"),20060); 
      Socket server = new Socket(AddressFamily.InterNetwork, 
           SocketType.Stream, ProtocolType.Tcp); 
      server.Connect(ipep); 

      String OutStr= "49|50|48|48|224|48|129|1|0|0|128|0|0|0|0|0|4|0|0|32|49|50"; 

      byte[] temp = OutStr.Split('|').Select(s => byte.Parse(s)).ToArray(); 

      int byteCount = server.Send(temp); 

      byte[] bytes = new byte[255]; 
      int res=0; 
      res = server.Receive(bytes); 
      return Encoding.UTF8.GetString(bytes); 

回答

6

用于接收数据的缓冲区大小取决于应用程序或协议。语言中没有办法告诉接收缓冲区的大小应该是多少。也没有任何可以使用的套接字函数说'你需要一个23867字节来接收这个消息'。一般而言,您的应用程序必须从协议中解决接收缓冲区的大小以及如何处理。通常协议将会:

  • 指定消息中的字节数。
  • (使用到0x7e指示消息的结尾例如HDLC)

这样做的结果是,您的应用程序可能需要处理斯普利特消息指定一个终止符。例如,服务器可能会发送2000字节的消息,但您的接收缓冲区只有1000字节,您必须编写一些代码来维护状态,告诉您是否已完成消息或部分完成。

+0

由于没有终止字符,有没有什么方法可以循环直到接收字节结束。 – Kanishka 2011-01-05 05:09:46

+0

@Kanishka通常使用多个系统页面大小来获得最佳性能。 http://msdn.microsoft.com/en-us/library/ms724958(v=vs.85).aspx – 2011-01-05 08:14:09

+1

@Kanishka:是的,看看这里http://msdn.microsoft.com/en-us/library /8s4y8aff.aspx。它概述了如何使用Socket.Receive来确定是否有更多数据等待在'Remarks'节中处理。 – sashang 2011-01-05 08:47:13

4

TCP是一个字节流。它对你的消息概念一无所知。

因此,您需要在该字节流内提供必要的消息成帧信息。常见的做法包括在邮件前加上一个包含邮件总长度的邮件头或用不能出现在有效邮件中的字符来终止邮件。

我在这里谈论TCP消息框架:http://www.serverframework.com/asynchronousevents/2010/10/message-framing-a-length-prefixed-packet-echo-server.html虽然它涉及C++代码,所以它可能对您没有任何用处。

对于消息使用者来说,处理长度前缀消息的性能通常稍高一些,而且消息生产者通常对消息生产者产生字符分隔的消息的性能往往略高一些。我个人更喜欢长度前缀的消息,只要有可能。

对于带长度前缀的消息,您首先会发送x字节的数据(消息的长度),然后对等方会知道它总是必须至少读取x个字节才能计算出长度,然后从该点开始知道结果消息的大小,并可以读取,直到它有很多字节。

使用字符分隔的消息,您只需继续阅读并扫描您已阅读的所有数据,直至找到消息分隔符。然后你会得到一个完整的消息,并且可能会有更多的数据(下一条消息的一部分?)放入缓冲区,然后再进行处理。

相关问题