I don't know if it's related to the WinSck bug, but it's so unpredictable and nasty that it makes me advice against using it.
As for the protocol, it's so woven into the other code that I can't extricate it with a reasonable amount of work. The principle is simple, though:
Sender: Send a package, prefixed with a package ID.
Reciever: Get the package. Return an acknowledge package with the id, basically "I got packet number 1234". If sender has already got package 1234, then do nothing more with it, else do whatever needs to be done.
Sender: If it doesn't get the ACK package within a certain time, resend package (which takes us back to the start). Ignore duplicate ACK packages with the same ID. If it gets the ACK, send next package.
Of course, the roles may be reversed if it's a two-way connection.
The sick thing about this is that this is exactly what TCP should take care of, so we won't need to. This is, more or less, what TCP does, but somehow, WinSck has messed that up.