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

百般思念 提交于 2019-12-01 11:53:25
Luaan

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

Let me point out some errors first:

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

Oh, and I have to recommend this essay on TCP protocol design.

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

NetworkStream.Read method has the following check inside:

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. 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!