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 < total)
{
if (total - bytesSent < 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();
}
}
BeginSend()
when you immediately synchronously wait for it to complete? Why don't you just useSend()
? Also, can you use C# 5.0? \$\endgroup\$ – svick Jun 28 '13 at 13:40