The socket implementation needs work, the packet processing needs work, but neither should require a complete rewrite
I'll do my best to help, just going through a bureaucracy-intense matter IRL that's keeping me busy.
€: The fragmentation you describe should not happen, even if our first recv() after the select()'s return doesn't poll all the data for the initial packet from the buffer, it will not poll data from a completely different packet inbetween calls. Assuming TCP of course, with UDP it's a simple matter of recv(), checking Size and discarding mismatches