Transmitting/Sending big packet safely using TcpClient/Socket I am writing a TCP based client that need to send and receive data. I have used the Asynchronous Programming Model (APM) provided for Socket class by the .NET Framework.

After being connected to the socket, I start waiting for data on the socket using BeginReceive.

Now, while I am waiting for the data on the Socket, I may need to send data over the socket. And the send method can be called multiple times, 

So I have make sure that


All the bytes from previous Send call is entirely sent.
The way I am sending the Data is safe considering that, while a data send is in progress, any call to send data can be made.


This is my first work on socket, So is my approach right to send data ?

    private readonly object writeLock = new object();
    public void Send(NetworkCommand cmd)
    {
        var data = cmd.ToBytesWithLengthPrefix();
        ThreadPool.QueueUserWorkItem(AsyncDataSent, data);
    }

    private int bytesSent;
    private void AsyncDataSent(object odata)
    {
        lock (writeLock)
        {
            var data = (byte[])odata;
            int total = data.Length;
            bytesSent = 0;
            int buf = Globals.BUFFER_SIZE;
            while (bytesSent &lt; total)
            {
                if (total - bytesSent &lt; Globals.BUFFER_SIZE)
                {
                    buf = total - bytesSent;
                }
                IAsyncResult ar = socket.BeginSend(data, bytesSent, buf, SocketFlags.None, DataSentCallback, data);
                ar.AsyncWaitHandle.WaitOne();
            }
        }
    }


How object is changed into byte[], sometimes the NetworkCommand can be as big as 0.5 MB

    public byte[] ToBytesWithLengthPrefix()
    {
        var stream = new MemoryStream();
        try
        {
            Serializer.SerializeWithLengthPrefix(stream, this, PrefixStyle.Fixed32);
            return stream.ToArray();
        }
        finally
        {
            stream.Close();
            stream.Dispose();
        }
    }
Instead of using the ToArray() method of the MemoryStream you could use GetBuffer() instead because this isn't creating a new array. 

Edit based on @Iridium's comment  

But this is only good if you use one of the constructor that creates a not resizable MemoryStream which isn't the case for the default constructor.  

Calling Dispose() on the MemoryStream closes the stream too.  

If you enclose the stream inside inside a using block the disposing of the stream will be handled automatically.

public byte[] ToBytesWithLengthPrefix()
{
    using (var stream = new MemoryStream())
    {
        Serializer.SerializeWithLengthPrefix(stream, this, PrefixStyle.Fixed32);
        return stream.ToArray();
    }
}




I needed to look twice at var data = (byte[])odata; which is a clear sign that you should make the method argument odata easier to distinguish from data, so objectData or dataToSend would be better.  

int buf isn't well named either. One shouldn't use abbreviations to name variables. A much better name would be for instance dataSize or just size to indicate that it is the amount of data being sent.