public void SendData() { // Состав отсылаемого универсального сообщения // 1. Заголовок о следующим объектом класса подробной информации дальнейших байтов // 2. Объект класса подробной информации о следующих байтах // 3. Байты непосредственно готовых к записи в файл или для чего-то иного. SendInfo si = new SendInfo(); si.message = Parent.Server_response; // Если нет сообщения и отсылаемого файла продолжать процедуру отправки нет смысла. if (String.IsNullOrEmpty(si.message) == true && String.IsNullOrEmpty(SendFileName) == true) { return; } if (SendFileName != null) { FileInfo fi = new FileInfo(SendFileName); if (fi.Exists == true) { si.filesize = (int)fi.Length; si.filename = fi.Name; } fi = null; } BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); bf.Serialize(ms, si); ms.Position = 0; byte[] infobuffer = new byte[ms.Length]; int r = ms.Read(infobuffer, 0, infobuffer.Length); ms.Close(); byte[] header = GetHeader(infobuffer.Length); byte[] total = new byte[header.Length + infobuffer.Length + si.filesize]; Buffer.BlockCopy(header, 0, total, 0, header.Length); Buffer.BlockCopy(infobuffer, 0, total, header.Length, infobuffer.Length); // Если путь файла указан, добавим его содержимое в отправляемый массив байтов if (si.filesize > 0) { FileStream fs = new FileStream(SendFileName, FileMode.Open, FileAccess.Read); fs.Read(total, header.Length + infobuffer.Length, si.filesize); fs.Close(); fs = null; } // Отправим данные подключенным клиентам NetworkStream ns = _tcpClient.tcpClient.GetStream(); // Так как данный метод вызывается в отдельном потоке рациональней использовать синхронный метод отправки ns.Write(total, 0, total.Length); // Обнулим все ссылки на многобайтные объекты и попробуем очистить память header = null; infobuffer = null; total = null; SendFileName = null; GC.Collect(); GC.WaitForPendingFinalizers(); // Подтверждение успешной отправки Parent.ShowReceiveMessage("Данные успешно отправлены!"); }
/// <summary> /// Метод асинхронно вызываемый при наличие данных в буферах приема. /// </summary> public void ReadCallback(IAsyncResult ar) { if (modeNetwork == Mode.indeterminately) { return; } TcpClientData myTcpClient = (TcpClientData)ar.AsyncState; try { NetworkStream ns = myTcpClient.tcpClient.GetStream(); int r = ns.EndRead(ar); if (r > 0) { // Из главного заголовка получим размер массива байтов информационного объекта string header = Encoding.Default.GetString(myTcpClient.buffer); int leninfo = int.Parse(header); // Получим и десериализуем объект с подробной информацией о содержании получаемого сетевого пакета MemoryStream ms = new MemoryStream(leninfo); byte[] temp = new byte[leninfo]; r = ns.Read(temp, 0, temp.Length); ms.Write(temp, 0, r); BinaryFormatter bf = new BinaryFormatter(); ms.Position = 0; SendInfo sc = (SendInfo)bf.Deserialize(ms); ms.Close(); if (sc.filesize > 0) { // Создадим файл на основе полученной информации и массива байтов следующих за объектом информации FileStream fs = new FileStream(sc.filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, sc.filesize); do { temp = new byte[global.MAXBUFFER]; r = ns.Read(temp, 0, temp.Length); // Записываем строго столько байтов сколько прочтено методом Read() fs.Write(temp, 0, r); // Как только получены все байты файла, останавливаем цикл, // иначе он заблокируется в ожидании новых сетевых данных if (fs.Length == sc.filesize) { fs.Close(); fs = null; break; } }while (r > 0); temp = null; GC.Collect(); GC.WaitForPendingFinalizers(); } if (Receive != null) { Receive(this, new ReceiveEventArgs(sc)); } myTcpClient.buffer = new byte[global.LENGTHHEADER]; ns.BeginRead(myTcpClient.buffer, 0, myTcpClient.buffer.Length, new AsyncCallback(ReadCallback), myTcpClient); } else { DeleteClient(myTcpClient); // Событие клиент отключился if (Disconnected != null) { Disconnected.BeginInvoke(this, "Клиент отключился!", null, null); } } } catch (Exception e) { DeleteClient(myTcpClient); // Событие клиент отключился if (Disconnected != null) { Disconnected.BeginInvoke(this, "Клиент отключился аварийно!", null, null); } SoundError(); } }
public ReceiveEventArgs(SendInfo sendinfo) { _sendinfo = sendinfo; }