This is a recurring communication problem.
For a start: If your host side program is really the only one that initiates communication, then I would start by making sure that the host side always *finishes* each communication, ie takes all the response that can possibly come.
If either side can initiate, you may need to tag your communication events so that each side can keep reading until it gets the response to the event *it* started. (If you just try to flush with a timeout, you will still have the race that the device side may initiate just *after* you finish flushing.)