简体   繁体   English

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

[英]Specified argument was out of the range of valid values. Parameter name: size & Serial Port Communication

I need to create an application which requires communicating to an existent software using TCP/IP, where both mine and the other application will be using the port number specified below. 我需要创建一个应用程序,该应用程序需要使用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);
} 

What happens is, the program I am communicating with has some in-built language where it will understand the code that I send, and it will return data according to the code that I have sent. 发生的是,我正在与之通信的程序具有某种内置语言,它将可以理解我发送的代码,并根据我发送的代码返回数据。 So in the code above, I sent three bits of code: ( "PCK|SCAN|5025066840471" ) which will find a specific item in the database. 因此,在上面的代码中,我发送了三位代码:( "PCK|SCAN|5025066840471" ),它将在数据库中找到特定的项目。 When it runs, I get an error on the line: 当它运行时,我在网上得到一个错误:

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

the error shows the following: "Specified argument was out of the range of valid values. Parameter name: size" 错误显示如下:“指定的参数超出有效值范围。参数名称:大小”

I followed the tutorial I saw on this website: http://csharp.net-informations.com/communications/csharp-client-socket.htm - But I did slightly different. 我遵循了在该网站上看到的教程: http : //csharp.net-informations.com/communications/csharp-client-socket.htm-但是我做的略有不同。 So instead of putting 所以不要放

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

I wrote: 我写:

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

I am extremely confused on why I am getting those problems, and to be honest I am not understanding much of what the code is doing, I just have a rough idea, but not enough to troubleshoot this. 我对为什么会遇到这些问题感到非常困惑,并且说实话,我对代码在做什么并不了解,我只是有一个大概的主意,但不足以解决此问题。 Can someone help please? 有人可以帮忙吗?

Much appreciated! 非常感激!

PS: I am programming for Windows CE (portable device) on Visual Studio 2010. PS:我正在Visual Studio 2010上为Windows CE(便携式设备)编程。

Your code is a great example of how not to do TCP communication. 您的代码很好地说明了如何不进行TCP通信。 I've seen this code copied over and over many times, and I'd be very happy to point you to a good tutorial on TCP - too bad I haven't seen one yet :) 我已经看过很多遍此代码了,很高兴为您指出一个关于TCP的好教程-太糟糕了,我还没看过:)

Let me point out some errors first: 首先让我指出一些错误:

  • TCP doesn't guarantee you the packet arrives as one bunch of bytes. TCP不能保证数据包以一束字节的形式到达。 So (theoretically) the Write operation could result in a split, requiring two reads on the other side. 因此(理论上), Write操作可能会导致拆分,从而需要在另一侧进行两次读取。 Sending data without headers over TCP is a very bad idea - the receiving side has no idea how much it has to read. 通过TCP发送不带标头的数据是一个非常糟糕的主意-接收方不知道必须读取多少数据。 So you've got two options - either write the length of the whole bunch of data before the data itself, or use a control character to end the "packet" 因此,您有两个选择-要么在数据本身之前写入整束数据的长度,要么使用控制字符结束“数据包”
  • The first point should also clarify that your reading is wrong as well. 第一点还应该阐明您的阅读也是错误的。 It may take more than a single read operation to read the whole "command", or a single read operation might give you two commands at once! 读取整个“命令”可能需要多个读取操作,或者一次读取操作可能一次给您两个命令!
  • You're reading ReceiveBufferSize bytes into a 10025 long buffer. 您正在将ReceiveBufferSize字节读取到10025长的缓冲区中。 ReceiveBufferSize might be bigger than your buffer. ReceiveBufferSize可能大于缓冲区。 Don't do that - read a max count of inStream.Length . 不要那样做-读取inStream.Length的最大数量。 If you were coding in C++, this would be a great example of a buffer overflow. 如果您使用C ++进行编码,这将是缓冲区溢出的一个很好的例子。
  • As you're converting the data to a string, you're expecting the whole buffer is full. 当您将数据转换为字符串时,您期望整个缓冲区已满。 That's most likely not the case. 事实并非如此。 Instead, you have to store the return value of the read call - it tells you how many bytes were actually read. 相反,您必须存储read调用的返回值-它告诉您实际读取了多少字节。 Otherwise, you're reading garbage, and basically having another buffer overflow. 否则,您正在读取垃圾,并且基本上有另一个缓冲区溢出。

So a much better (though still far from perfect) implementation would be like this: 因此,更好的实现(尽管还远远不够完美)将是这样的:

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);

Oh, and I have to recommend this essay on TCP protocol design . 哦,我必须推荐这篇有关TCP协议设计的文章

It talks about many of the misconceptions about TCP, most importantly see the Message Framing part. 它讨论了有关TCP的许多误解,最重要的是请参阅消息框架部分。

NetworkStream.Read method has the following check inside: NetworkStream.Read方法内部进行以下检查:

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

In your case: 在您的情况下:

size = clientSocket.ReceiveBufferSize

offset = 0

buffer = inStream

The error you received means that clientSocket.ReceiveBufferSize > inStream.Length . 您收到的错误意味着clientSocket.ReceiveBufferSize> inStream.Length In other words you are trying to read more bytes than are available. 换句话说,您尝试读取的字节数多于可用字节数。 Try to use the following code: 尝试使用以下代码:

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

See also an example here . 还看到一个例子在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 指定的参数超出有效值范围。 参数名称:大小 - Specified argument was out of the range of valid values. Parameter name: size 指定的参数超出了有效值的范围。 参数名称:值 - Specified argument was out of the range of valid values. Parameter name: value 得到“指定的参数超出有效值范围。 参数名称:” - Getting “Specified argument was out of the range of valid values. Parameter name:” 指定的参数超出有效值范围。 参数名称:site - Specified argument was out of the range of valid values. Parameter name: site 异常:指定的参数超出有效值的范围。 (参数“索引”) - Exception: Specified argument was out of the range of valid values. (Parameter 'index') FastMember:指定的参数超出有效值范围。 参数名称:名称 - FastMember: Specified argument was out of the range of valid values. Parameter name: name System.ArgumentOutOfRangeException: &#39;指定的参数超出了有效值的范围。 参数名称:asp.net中的index&#39; - System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values. Parameter name: index' in asp.net 指定的参数超出了有效值的范围。参数名称:site - 由于创建者更新而导致的错误 - Specified argument was out of the range of valid values. Parameter name: site - Error Due To Creators Update MEF指定的参数超出有效值范围。 参数名称:site - MEF Specified argument was out of the range of valid values. Parameter name: site 指定的参数超出有效值范围。 参数名称索引。 由ObservableCollection.Add()方法抛出 - Specified argument was out of the range of valid values. parameter name index. thrown by ObservableCollection.Add() method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM