指定的参数超出了有效值的范围。 参数名称:大小和串口通信

我需要创建一个应用程序,它需要使用TCP / IP与现有软件进行通信,其中我和其他应用程序将使用下面指定的端口号。

private void frmScan_Load(object sender, EventArgs e) { clientSocket.Connect("100.100.100.30", 76545); } public void msg(string mesg) { textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + mesg; } private void cmdSCANok_Click(object sender, EventArgs e) { msg("Client Started"); NetworkStream serverStream = clientSocket.GetStream(); byte[] outStream = Encoding.ASCII.GetBytes("PCK|SCAN|5025066840471"); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); byte[] inStream = new byte[10025]; serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize); string returndata = Encoding.ASCII.GetString(inStream, 0, inStream.Length); msg("Data from Server : " + returndata); } 

发生的事情是,我正在与之通信的程序有一些内置语言,它将理解我发送的代码,它将根据我发送的代码返回数据。 所以在上面的代码中,我发送了三位代码:( "PCK|SCAN|5025066840471" ),它将在数据库中找到一个特定的项目。 运行时,我收到错误:

 serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize); 

错误显示以下内容:“指定的参数超出有效值范围。参数名称:大小”

我按照我在本网站上看到的教程: http : //csharp.net-informations.com/communications/csharp-client-socket.htm – 但我做的略有不同。 所以不要放

 string returndata = Encoding.ASCII.GetString(inStream); 

我写:

 string returndata = Encoding.ASCII.GetString(inStream, 0, inStream.Length); 

我对于为什么会遇到这些问题感到非常困惑,说实话,我对代码的作用并不了解,我只是有一个粗略的想法,但还不足以解决这个问题。 有人可以帮忙吗?

非常感激!

PS:我正在为Visual Studio 2010上的Windows CE(便携式设备)编程。

您的代码是如何不进行TCP通信的一个很好的例子。 我已经多次看到这段代码被复制了,我很高兴为您指出一个关于TCP的好教程 – 太糟糕了我还没见过一个:)

我先指出一些错误:

  • TCP不保证数据包以一串字节的forms到达。 因此(理论上) Write操作可能导致拆分,另一方面需要两次读取。 通过TCP发送没有标题的数据是一个非常糟糕的主意 – 接收方不知道它需要读多少。 所以你有两个选择 – 在数据本身之前写入整组数据的长度,或者使用控制字符来结束“数据包”
  • 第一点也应该澄清你的阅读也是错误的。 读取整个“命令”可能需要多个读取操作,或者单个读取操作可能会同时为您提供两个命令!
  • 您正在将ReceiveBufferSize字节读入10025长缓冲区。 ReceiveBufferSize可能比您的缓冲区大。 要这样做 – 读取inStream.Length的最大计数。 如果您使用C ++进行编码,这将是缓冲区溢出的一个很好的例子。
  • 当您将数据转换为字符串时,您希望整个缓冲区已满。 这很可能不是这种情况。 相反,您必须存储读取调用的返回值 – 它告诉您实际读取了多少字节。 否则,你正在读垃圾,基本上有另一个缓冲区溢出。

所以更好(但仍然远非完美)的实现将是这样的:

 NetworkStream serverStream = clientSocket.GetStream(); byte[] outStream = Encoding.ASCII.GetBytes("PCK|SCAN|5025066840471"); // It would be much nicer to send a terminator or data length first, // but if your server doesn't expect that, you're out of luck. serverStream.Write(outStream, 0, outStream.Length); // When using magic numbers, at least use nice ones :) byte[] inStream = new byte[4096]; // This will read at most inStream.Length bytes - it can be less, and it // doesn't tell us how much data there is left for reading. int bytesRead = serverStream.Read(inStream, 0, inStream.Length); // Only convert bytesRead bytes - the rest is garbage string returndata = Encoding.ASCII.GetString(inStream, 0, bytesRead); 

哦,我必须推荐这篇关于TCP协议设计的文章 。

它讨论了许多关于TCP的误解,最重要的是看到消息框架部分。

NetworkStream.Read方法内部有以下检查:

 if(size < 0 || size > (buffer.Length - offset)) throw new ArgumentOutOfRanveException("size"); 

在你的情况下:

 size = clientSocket.ReceiveBufferSize offset = 0 buffer = inStream 

您收到的错误意味着clientSocket.ReceiveBufferSize> inStream.Length 。 换句话说,您正在尝试读取比可用字节更多的字节。 尝试使用以下代码:

 ... var count = serverStream.Read(inStream, 0, inStream.Length); string returndata = Encoding.ASCII.GetString(inStream, 0, count); 

另请参见此处的示例。