By far the easiest way to transmit a fixed amount of data over a serial port in one shot is to prepend the data with a length header. Use a fixed number of bytes for the length (2-4 should suffice) and then read length
bytes of data synchronously using the Read
method. You can do this asynchronously too, of course, you just need to save the length in a member field somewhere and perform your post-processing as soon as the length is hit.
The next-best way is to append a stop character or word. If it happens to be a newline, then you can use the synchronous SerialPort.ReadLine method. Otherwise, collect the received data in a StringBuilder
, keep appending to the StringBuilder
until you hit the stop character, then return the contents of that StringBuilder
up to (but excluding) the stop character.
If you do not have control over the source data, need to read a fixed amount of data, and don't know what that size is in advance, then your job is going to be considerably more difficult. I think the only way of really dealing with this situation is to wait for a predetermined timeout, at which point you assume that the transmission is over if you haven't received any new data. It's not particularly reliable, which is why most communication protocols use one of the aforementioned designs.
If you think about the way a serial port (or any port) works, by simply pushing bits over a wire, then it should be clear that there's no way to know whether or not a transmission has completed without being able to predict the future. If you're connected to a remote host, i.e. over a modem, and that host disconnects you when the transmission is finished, then you might be able to use the Carrier Detect, but that doesn't sound like the case here.
Hopefully this is not the scenario you're currently in, and either you have some ability to control the source data or the device you're connecting to already uses a length header and/or stop pattern. If it does, definitely use that. Otherwise, you'll probably be stuck using timeouts.