I don't think it is a fix at all, just luck.
If you unroll the client and server main loops, you get the same thing: send/receive/send/receive/send/receive/... there's not one before the other, because the whole thing loops. Swapping the receive and send calls changes nothing. If I had to guess why your second code works better than the first one, I'd say that this is because of vertical-sync. With vertical-sync enabled, window.display() is what takes most of the main loop's time. And since you have the receive call before, and the send call after, it makes the client and server somehow synchronized so that when one sends, the other is receiving and the other way round.
But back to the real problem now. When the you call receive() on client side, the whole execution is blocked until some data is received. Now everything's fine if the server just issued a call to send(). But what if both client and server arrive at the receive() call at the same time? Both will be stuck waiting for some data from each other. Which will never happen because they can't send as long as they are waiting to receive something.
So I think that your design is flawed. You should read more networking tutorials (I mean generic ones, not specifically tied to a library). In short: make your sockets non-blocking if you want them to stay in the main thread (best option) or use threads to avoid blocking the application while you're waiting for network data.