//public string SendFileName = null; public void SendData(NetworkTransferObjects obj, ProtocolOfExchange protokolMsg) { // Состав отсылаемого универсального сообщения // 1. Заголовок о следующим объектом класса подробной информации дальнейших байтов // 2. Объект класса подробной информации о следующих байтах // 3. Байты непосредственно готовых к записи в файл или для чего-то иного. try { SendInfo si = new SendInfo(); si.ProtocolMsg = protokolMsg; // Если нет сообщения и отсылаемого файла продолжать процедуру отправки нет смысла. //if (si.message == null && obj==null) return; byte[] _obj_arr;// = new byte[10]; if (obj != null) { BinaryFormatter _bf = new BinaryFormatter(); MemoryStream _ms = new MemoryStream(); _bf.Serialize(_ms, obj); si.datasize = (int)_ms.Length; _obj_arr = _ms.ToArray(); _ms.Close(); } else { si.datasize = 0; _obj_arr = 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.datasize]; Buffer.BlockCopy(header, 0, total, 0, header.Length); Buffer.BlockCopy(infobuffer, 0, total, header.Length, infobuffer.Length); // Если путь файла указан, добавим его содержимое в отправляемый массив байтов if (si.datasize > 0 && _obj_arr != null) { Buffer.BlockCopy(_obj_arr, 0, total, header.Length + infobuffer.Length, si.datasize); } // Отправим данные подключенным клиентам NetworkStream ns = _tcpClient.tcpClient.GetStream(); // Так как данный метод вызывается в отдельном потоке рациональней использовать синхронный метод отправки ns.Write(total, 0, total.Length); // Обнулим все ссылки на многобайтные объекты и попробуем очистить память header = null; infobuffer = null; total = null; //Parent.labelFileName.Text = ""; GC.Collect(); GC.WaitForPendingFinalizers(); } catch (Exception e) { SoundError(e.Message); } // Подтверждение успешной отправки // 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(); object obj = null; if (sc.datasize > 0) { // Создадим файл на основе полученной информации и массива байтов следующих за объектом информации // FileStream fs = new FileStream(sc.filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, sc.filesize); BinaryFormatter _bf = new BinaryFormatter(); MemoryStream _ms = new MemoryStream(); do { temp = new byte[global.MAXBUFFER]; r = ns.Read(temp, 0, temp.Length); // Записываем строго столько байтов сколько прочтено методом Read() _ms.Write(temp, 0, r); // Как только получены все байты файла, останавливаем цикл, // иначе он заблокируется в ожидании новых сетевых данных if (_ms.Length == sc.datasize) { _ms.Position = 0; obj = _bf.Deserialize(_ms); _ms.Close(); break; } }while (r > 0); temp = null; GC.Collect(); GC.WaitForPendingFinalizers(); } if (Receive != null) { Receive(this, new ReceiveEventArgs(sc, (NetworkTransferObjects)obj)); } 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(e.Message); } }
public ReceiveEventArgs(SendInfo sendinfo, NetworkTransferObjects obj) { _sendinfo = sendinfo; _object = obj; }