Update
The Flash documentation team has confirmed the documentation is incorrect. Data is sent as soon as you write to the Socket.
Flash's Socket class documentation says the following:
flush() method
Flushes any accumulated data in the socket's output buffer. Data written by the write methods is not immediately transmitted; it is queued until the flush() method is called.
Unfortunately, this is not the case. The moment you write to a connected socket, it sends the data and the server receives it. You do not need to call flush(), and, in fact, calling flush() has no effect as far as the server or Flash is concerned.
The socket automatically sends as little as 1 byte. socket.writeByte(0) is immediately sent across the socket. Data is not queued, it is immediately transmitted, so calling flush() doesn't do anything because the data is already sent. There is no difference from the server's perspective whether I call flush() or not, and I can write millions of bytes on a Socket and never call flush() and there is no negative effect as far as all testing I have conducted has been able to show.
Based on my tests, Flash sends data across the Socket in 536 byte packets. Anything larger than 536 bytes gets split into separate packets. So, if you send 537 bytes, Flash sends two packets, one that's 536 bytes and one that's 1 byte.
The internal limit that Flash can send via Socket appears to be 524,744 bytes. If you set up your server to not read off the socket, 524,744 bytes is the point that Flash's socket becomes blocked. However, Flash does not let you know that the Socket is blocked or that there are any bytes sitting on the Socket unsent.
This behavior is exacerbated by the fact that there is no way to track progress on Socket sending, only receiving. There is no event that fires if you're blocked, and you have no way of knowing that the server did not receive your entire transmission unless you have some kind of expected response that you did not receive within a certain time limit, which is not something you can reliably measure considering latency and/or varying bandwidths, and the fact that you have no idea how much data the server has received.
If you send 1,000,000 bytes and set up your server to wait until you send 524,744 bytes to read it, Flash does not even need you to call flush() to send the remaining 475,256 bytes, it happens automatically. No flush() required, and you don't even know that the Socket was blocked.
It's worth pointing out that if the server has a receive buffer (we set it to 8040 bytes), Flash does not honor it when running in the IDE, running as a SWF in the debug player on the desktop, or in AIR. It only honors it when it's running in a browser (tested in Chrome, Firefox and IE on Windows). Regardless, Flash does not report that only 8040 bytes were sent, and, again, flush() was not called but the bytes were sent anyway.
The behavior is identical whether you use socket.writeByte() and write 1 byte to the socket at a time, or use writeBytes() and write all the bytes to the socket at once.
FileReference lets you track progress on a HTTP Socket POST of bytes. I hope they soon will give us progress on the Socket sending, and, perhaps, allow the Socket to wait for you to tell it to upload (via flush()).