I've implemented a async funtion in order to read large socket data, mostly files will be transferred. Code is based on this question:
public class StateObject
{
public Socket workSocket = null;
public const int BUFFER_SIZE = 1024;
public byte[] buffer = new byte[BUFFER_SIZE];
public StringBuilder sb = new StringBuilder();
}
public static void Read_Callback(IAsyncResult ar)
{
StateObject so = (StateObject) ar.AsyncState;
Socket s = so.workSocket;
int read = s.EndReceive(ar);
if (read > 0)
{
so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));
if (read == StateObject.BUFFER_SIZE)
{
s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0,
new AyncCallback(Async_Send_Receive.Read_Callback), so);
return;
}
}
if (so.sb.Length > 0)
{
//All of the data has been read, so displays it to the console
string strContent;
strContent = so.sb.ToString();
Console.WriteLine(String.Format("Read {0} byte from socket" +
"data = {1} ", strContent.Length, strContent));
}
s.Close();
}
After all of the data has been captured in the stringbuilder, I decrypt it and convert the base64 string to a file using another method. There will be multiple socket receiving\sending files so every workersocket has an ID.
Now here's the case; I want some status on the receiving file. For example a progress bar showing how much is received and the total amount to be received. The Read_Callback method uses a recursive call in order to get all the data from the socket, which prevents me from getting the total amount to be received. Does anyone know how to get the total amount the socket has to receive? Or is my only option to send the size fixed to the listener before transferring the data?
As mentioned before, my stateobject class contains an ID for identifying the socket which the data is for. Upon first connection, the program stores the connection and received info in an arraylist.
In order to get the amount of bytes already read, I have to report the status to one of the initiated worker classes stored in the arraylist. If I want to do this during the recursive call, how will I perform this without losing performance when receiving data?
As last, which buffer size should be used? should this be the MTU of tcp which is 1500 bytes in most cases?
Note: I'm fairly new to C# programming, feel free to comment on bad practices or anything else.