serial port - c#: strange shift in data buffer during communication with device -
in app have receive , process data device, connected through com port. partially. in particular device first 2 bytes length of packet (minus 2 since doesn't take account these 2 bytes; length of rest of packet after all). then, since know device tends send me data slowly, read rest of packet in loop, until data has been read. right here encountered strange problem. let's assume entire packet (including these first 2 bytes length) looks this: ['a', 'b', 'c', 'd', 'e']. when read first 2 bytes ('a' , 'b'), i'd expect rest of packet this: ['c', 'd', 'e']. instead, looks this: ['b', 'c', 'd', 'e']. how come second byte of response still in read buffer? , why second one, without previous one?
the code below shows how handle communication process:
//the data array array output data //the size array two-byte array store frame-length bytes //the results array device's response //the part array part of response that's in read buffer port.write(data, 0, data.length); //receiving device's response (if there's any) try { port.read(size, 0, 2); //read first 2 bytes (packet's length) of response //we'll store entire response in results array. size first 2 bytes of response //(+2 these bytes since they're not counted in device's data frame) results = new byte[(size[0] | ((int)size[1] << 8)) + 2]; results[0] = size[0]; results[1] = size[1]; //we'll need packet size checksum count //time read rest of response for(offset = 2; offset < results.length && port.bytestoread > 0; offset += part.length) { system.threading.thread.sleep(5); //device's quite slow, isn't try { part = new byte[port.bytestoread]; port.read(part, 0, part.length); //here's old data being read } catch(system.timeoutexception) { //handle somehow } buffer.blockcopy(part, 0, results, offset, part.length); } if(offset < results.length) //something went wrong during receiving response throw new exception(); } catch(exception) { //handle somehow }
you making traditional mistake, cannot ignore return value of read(). tells how many bytes actually received. @ least 1, not more count. many present in receive buffer, bytestoread tells you. keep calling read() until happy:
int cnt = 0; while (cnt < 2) cnt += port.read(size, cnt, 2 - cnt);
just use same code in 2nd part of code don't burn 100% core without sleep() call. keep in mind timeoutexception when read size, more actually. fatal exception if thrown when cnt > 0, can't resynchronize anymore.
Comments
Post a Comment