Problem with serial port data receive in C#
I have a problem with a C# program. Through the Serial port i Receive a large string about 110 characters. This part works ok, but when i add code to split the string up i receive an error after some rows. Here is the error I get:
**An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
Additional information: Index and length must refer to a location within the string.**
Here is the code:
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (!comport.IsOpen) return;
if (CurrentDataMode == DataMode.Text)
{
// Read all the data waiting in the buffer
string data = comport.ReadExisting();
Log(LogMsgType.Incoming, data);
string ziua = data.Substring(0, 8);
string ora = data.Substring(8, 8);
string linie = data.Substring(18, 1);
string interior = data.Substring(22, 3);
string durata1 = data.Substring(26, 4);
string durata2 = data.Substring(30, 8);
string nrtel = data.Substring(38, 10);
string tipapel = data.Substring(75, 1);
string acct = data.Substring(76, 5);
}
else
{
int bytes = comport.BytesToRead;
byte[] buffer开发者_JS百科 = new byte[bytes];
comport.Read(buffer, 0, bytes);
Log(LogMsgType.Incoming, ByteArrayToHexString(buffer));
}
}
EDIT:
i've tested every substring and all of them are ok. the string lenght is 112. it can't be to short.
this error appears after a few lines of 112... about one and a half
This is typical behavior for a serial port. They are very slow. When the DataReceived event fires, you'd typically only get one or two characters. Notably is that it works well when you debug because single-stepping through the code gives the serial port lots of time to receive additional characters. But it will go Kaboom as soon as you run without a debugger because the string isn't long enough.
You'll need to modify the code by appending the string you receive to a string variable at class scope. Only parse the string after you've received all the characters you expected. You'll need some way to know that you've received the full response. Most typically serial devices will terminate the string with a special character. Often a line-feed.
If that's the case then you can make it easy by setting the SerialPort.NewLine property to that terminator and calling ReadLine() instead of ReadExisting().
The length of "data" is probably too short for one of the calls to "Substring". Check the length of the string that you expect before accessing parts of it that may not exist.
You don't check what you have enough data before processing. SerialPort.ReadExisting Method just
Reads all immediately available bytes, based on the encoding, in both the stream and the input buffer of the SerialPort object.
Your device maybe just don't have time to pass all data. So you need rewrite your logic to concatenate incoming data and process it after receiving enough data.
The exception is telling you that, at some point, Substring
is being given parameters that exceed the length of the string. Which likely means you aren't getting the data you are expecting from the serial port. Try inserting a breakpoint at the first call to Substring
and check the contents of data
to make sure the device you are reading from isn't sending some kind of error code or something other than what your code expects.
You should verify the length of your string before your start splitting it up. Put a conditional in there to handle the case where the string is less than what you expect, and then see if the errors persist.
Try make a length check for each variable assignment like this:
string acct = (data.length >= 81) ? data.Substring(76, 5) : string.empy;
The data.length could be shorter than the total length of your substring (76 + 5).
精彩评论