private CommandResult SendCommand(byte commandNumber, byte[] data) { if (commandNumber == 0) { _currentAddress = new ShortAddress(0); } if (AutomaticZeroCommand && commandNumber != 0 && !(_currentAddress is LongAddress)) { SendZeroCommand(); } Command command; if (commandNumber == 0) { command = Command.Zero(PreambleLength); _currentAddress = new LongAddress(0, 1, new byte[] { 2, 3, 4 }); } else { command = new Command(PreambleLength, _currentAddress, commandNumber, new byte[0], data); } if (SendingCommand != null) { SendingCommand.BeginInvoke(this, new CommandRequest(command), null, null); } command.ResponseCode = new byte[] { 0, 0 }; Thread.Sleep(5); // give chance to handle sending event if (Receive != null) { Receive.BeginInvoke(this, new CommandResult(command), null, null); } return(new CommandResult(command)); }
/// <summary> /// Метод асинхронно вызываемый при наличие данных в буферах приема. /// </summary> public void ReadCallback(IAsyncResult ar) { if (ModeNetwork == Mode.Indeterminately) { return; } var myTcpClient = (TcpClientData)ar.AsyncState; try { var ns = myTcpClient.TcpClient.GetStream(); var r = ns.EndRead(ar); if (r > 0) { // Из главного заголовка получим размер массива байтов информационного объекта var sendinfolen = GetLengthByHeader(myTcpClient.Buffer); // Получим и десериализуем объект с подробной информацией о содержании получаемого сетевого пакета var ms = new MemoryStream(sendinfolen); var temp = new byte[sendinfolen]; r = ns.Read(temp, 0, temp.Length); ms.Write(temp, 0, r); var bf = new BinaryFormatter(); ms.Position = 0; var sc = (SendInfo)bf.Deserialize(ms); ms.Close(); if (sc.Filesize > 0) { var templength = sc.Filesize + sc.Padding; // Создадим файл на основе полученной информации и массива байтов следующих за объектом информации if (DstDirectory.LastIndexOf("\\", StringComparison.Ordinal) + 1 != DstDirectory.Length) { DstDirectory += "\\"; } var fs = new FileStream(DstDirectory + sc.Filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, sc.Filesize); //если файл шифрованный, то сначала проще собрать в памяти var tempms = new MemoryStream(); temp = new byte[Global.Maxbuffer]; do { while (templength > 0) { if (templength < temp.Length) { //считываем по длине файла r = ns.Read(temp, 0, templength); templength -= r; } else { //считываем по длине буффера r = ns.Read(temp, 0, temp.Length); templength -= r; } // Записываем строго столько байтов сколько прочтено методом Read() //fs.Write(temp, 0, r); tempms.Write(temp, 0, r); } // Как только получены все байты файла, останавливаем цикл, // иначе он заблокируется в ожидании новых сетевых данных if (tempms.Length != sc.Filesize + sc.Padding) { continue; } //теперь если файл шифрованный, то расшифруем его tempms.Seek(0, SeekOrigin.Begin); if (sc.IsFileCrypt) { var iv = new byte[16]; var cipherStream = (CryptoStream)_engine.DecryptStream(tempms, DiffieHellman.SecretKey, iv); using (var plainTextStream = new BinaryReader(cipherStream)) { var data = plainTextStream.ReadBytes(sc.Filesize); fs.Write(data, 0, sc.Filesize); } } else { //просто скопируем из памяти tempms.CopyTo(fs); } tempms.Close(); fs.Close(); break; } while (r > 0); GC.Collect(); GC.WaitForPendingFinalizers(); } if (Receive != null) { Receive.BeginInvoke(this, new ReceiveEventArgs(sc), null, null); } myTcpClient.Buffer = new byte[Global.Lengthheader]; ns.BeginRead(myTcpClient.Buffer, 0, myTcpClient.Buffer.Length, ReadCallback, myTcpClient); } else { DeleteClient(myTcpClient); // Событие клиент отключился if (Disconnected != null) { Disconnected.BeginInvoke(this, "Клиент отключился!", null, null); } } } catch (Exception) { DeleteClient(myTcpClient); // Событие клиент отключился if (Disconnected != null) { Disconnected.BeginInvoke(this, "Клиент отключился аварийно!", null, null); } SoundError(); } }