Я реализовал асинхронную функцию для чтения больших данных сокетов, в основном файлы будут передаваться. Код основан на этом вопросе :
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();
}
После того как все данные были собраны в строителе строк, я расшифровываю их и преобразую строку base64 в файл другим способом. Будет несколько сокетов, принимающих \ отправляющих файлы, поэтому каждый рабочий сокет имеет идентификатор.
Теперь вот случай; Я хочу получить статус в файле получения. Например, индикатор выполнения, показывающий, сколько получено, и общую сумму, которую нужно получить. Метод Read_Callback использует рекурсивный вызов, чтобы получить все данные из сокета, что не позволяет мне получить общую сумму, которую необходимо получить. Кто-нибудь знает, как получить общую сумму, которую должен получить сокет? Или мой единственный способ отправить фиксированный размер слушателю перед передачей данных?
Как упоминалось ранее, мой класс stateobject содержит идентификатор для идентификации сокета, для которого предназначены данные. При первом соединении программа сохраняет соединение и полученную информацию в массиве.
Чтобы получить количество прочитанных байтов, я должен сообщить о состоянии одному из инициированных рабочих классов, хранящихся в массиве. Если я хочу сделать это во время рекурсивного вызова, как я буду выполнять это без потери производительности при получении данных?
Как последний, какой размер буфера следует использовать? должен ли это быть MTU tcp, который в большинстве случаев составляет 1500 байт?