指定的参数超出了有效值的范围。 参数名称:大小和串口通信
我需要创建一个应用程序,它需要使用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);
另请参见此处的示例。