Exemple #1
0
        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();
            }
        }