If you're not receiving all the data, do another read() to get the rest. Like
any stream, you're not guaranteed it all in one go. If you've been assuming you always get it all at once, that's probably where the garbage is coming from too -- writing data you never got, and starting halfway through other things when you start the "next" struct. If you're sending fixed size data structures back and forth you might consider packet sockets instead of stream ones; UDP packets will always arrive whole. They can't hold much more than one kilobyte per packet though.
Also, please post your actual code. If you have perrors everywhere then you clipped an awful lot of error checking to post that here; most of our suggestions would be "check z's return value" when you're already doing so.