Better thread management

For the sending thread, I removed the Thread.currentThread().sleep()
call, and instead implemented a wait/notifyAll scheme so that the thread
automatically resumes when either a packet is ready, or a set timeout,
say 100ms (entirely arbitrary, but slow enough to not cause too much CPU
use).