ensure nonblock loop in Socket#write operates on a binary string

Ensures that String#size returns bytes and String#slice properly
references the bytes remaining. If +data+ is a UTF-8 encoded string with
multi-byte characters, this would cause data loss on partial writes, and
could cause +written+ to exceed +data.size+.