All I really want is when I get a mouse move event, to spit it out of the socket.
From the documentation you linked to:
A potential problem with stream processing is blocking. A thread that is writing to … a stream might have to wait indefinitely until there is … space on the stream to put bytes….
If you simply did a blocking write, you could block forever, hanging your application.
If you simply did a non-blocking write, you may only write part of what you intended to. This will confuse the other side if you don't remember what you have left and try to send it again later.
Enter the run loop. Mouse-move events come in on the run loop, too—you don't need or want a separate run loop. “Intersecting” the two sources of events is exactly what a run loop is for.
You'll want symmetry between your event handlers: Each should either send some bytes or remember some state (using a couple of instance variables for the latter).
In the mouse-moved handler, if you have previously received a has-space-available event and did not have a mouse-moved event to send, send the one you just got. Otherwise, remember the event for later. (Keep only one event at a time—if you get another one, throw the older one away.)
In the has-space-available handler, if you have a mouse-moved event that you have not sent, send it now. Otherwise, remember that you have space available, so you can use it at your next mouse-moved event.
Either way, when you try to write the bytes and only write some of them, remember the bytes and where you left off. You should only start sending a new mouse-moved event after completely sending a previous one.
Note that the solution as I have described it will drop events if you're getting events faster than you can send them out. This is not a problem: If you're getting them faster than you can send them out, and you keep them around until you can send them out, then either they will pile up and tip over (you run out of memory and your app crashes/your app stops working/you bog down the system) or the user will see instances of “catch-up” where the mouse on the receiving end slowly replays all the events as they slowly come in. I say it's better, in your case, to drop events you couldn't send and just let the receiving mouse teleport across space to make up the lost time.