指定的参数超出有效值范围.参数名称:size&串口通讯 [英] Specified argument was out of the range of valid values. Parameter name: size & Serial Port Communication

查看:58
本文介绍了指定的参数超出有效值范围.参数名称:size&串口通讯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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" ),它将在数据库中找到特定的项目.当它运行时,我在行上得到一个错误:

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. When it runs, I get an error on the line:

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

该错误显示以下内容:指定的参数超出有效值范围.参数名称:size"

the error shows the following: "Specified argument was out of the range of valid values. Parameter name: size"

我遵循了在该网站上看到的教程: http://csharp.net-informations.com/communications/csharp-client-socket.htm -但是我做的略有不同.所以不要放

I followed the tutorial I saw on this website: http://csharp.net-informations.com/communications/csharp-client-socket.htm - But I did slightly different. So instead of putting

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

我写道:

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?

非常感谢!

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

PS: I am programming for Windows CE (portable device) on Visual Studio 2010.

推荐答案

您的代码很好地说明了如何不进行TCP通信.我已经看过很多遍了,这段代码被复制了很多次,很高兴为您指出一个关于TCP的好教程-太糟糕了,我还没看过:)

Your code is a great example of how not to do TCP communication. 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不能保证数据包以一堆字节的形式到达.因此,(理论上) Write 操作可能会导致拆分,而另一端需要进行两次读取.通过TCP发送不带标题的数据是一个非常糟糕的主意-接收方不知道必须读取多少数据.因此,您有两个选择-或者在数据本身之前写一整串数据的长度,或者使用控制字符结束数据包"
  • 第一点还应该阐明您的阅读也是错误的.读取整个命令"可能需要多个读取操作,或者一次读取操作可能一次给您两个命令!
  • 您正在将 ReceiveBufferSize 字节读入 10025 长缓冲区中. ReceiveBufferSize 可能大于缓冲区.不要这样做-读取最大数量为 inStream.Length 的计数.如果您使用C ++进行编码,那么这将是缓冲区溢出的一个很好的例子.
  • 当您将数据转换为字符串时,您期望整个缓冲区已满.很有可能不是这种情况.相反,您必须存储read调用的返回值-它告诉您实际读取了多少字节.否则,您正在读取垃圾,并且基本上是另一个缓冲区溢出.
  • TCP doesn't guarantee you the packet arrives as one bunch of bytes. So (theoretically) the Write operation could result in a split, requiring two reads on the other side. Sending data without headers over TCP is a very bad idea - the receiving side has no idea how much it has to read. 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 might be bigger than your buffer. Don't do that - read a max count of inStream.Length. If you were coding in C++, this would be a great example of a buffer overflow.
  • 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. 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);

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

它讨论了有关TCP的许多误解,最重要的是请参阅消息框架"部分.

It talks about many of the misconceptions about TCP, most importantly see the Message Framing part.

这篇关于指定的参数超出有效值范围.参数名称:size&串口通讯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆