示例#1
0
        private static void Encode(BinaryWriter wtr, TcpPacketRequestFileTransportExtend extend)
        {
            byte[] buf   = BitConverter.GetBytes(extend.FileID);
            byte[] enBuf = SecurityFactory.Encrypt(buf, extend.EncryptKey);

            wtr.Write(enBuf.Length);
            wtr.Write(enBuf);
        }
        private static TcpPacketRequestFileTransportExtend ResolveRequestFileTransportExtend(BinaryReader rdr, byte[] priKey)
        {
            TcpPacketRequestFileTransportExtend extend = new TcpPacketRequestFileTransportExtend();
            int len = rdr.ReadInt32();

            byte[] buf = rdr.ReadBytes(len);

            byte[] deBuf = SecurityFactory.Decrypt(buf, priKey);
            extend.FileID = BitConverter.ToInt64(deBuf, 0);

            return(extend);
        }
示例#3
0
        private void SendFileHandler(object clientobj)
        {
            LoggerFactory.Debug("begin send file");

            TcpClient     client = null;
            NetworkStream ns     = null;

            try
            {
                client = clientobj as TcpClient;
                ns     = client.GetStream();

                if (!ns.CanRead)
                {
                    //想定外
                    ns.Close();
                    client.Close();
                    OnError(Errors.NotExistTransportId, "未收到传送ID", null, null);
                    return;
                }
            }
            catch (Exception e)
            {
                OnError(Errors.NetworkError, "尝试收取传送ID失败", null, e);
                return;
            }

            LoggerFactory.Debug("get file id");
            //取得传送的文件ID
            byte[] buff = null;
            int    len  = 0;

            try
            {
                buff = new byte[this.ReceiveBufferSize];
                len  = ns.Read(buff, 0, buff.Length);
            }
            catch (Exception e)
            {
                ns.Close();
                client.Close();
                OnError(Errors.NetworkError, "尝试收取传送ID失败", null, e);
                return;
            }

            TcpPacket packet = null;

            try
            {
                IPacketResolver resolver = PacketResolverFactory.CreateResolver(buff, 0, len, this.SecurityKeys.Private);
                packet = resolver.Resolve() as TcpPacket;
            }
            catch (Exception e)
            {
                ns.Close();
                client.Close();
                OnError(Errors.ResolveError, "解密文件ID失败", null, e);
                return;
            }

            LoggerFactory.Debug("get file");
            TcpPacketRequestFileTransportExtend extend = packet.Extend as TcpPacketRequestFileTransportExtend;

            if (!_transportFileDic.TryRemove(extend.FileID, out TransportFile file))
            {
                ns.Close();
                client.Close();
                OnError(Errors.NotExistTransportId, "不存在的文件ID=" + extend.FileID, null, null);
                return;
            }

            LanFile lanFile = file.File;

            if (!File.Exists(lanFile.Path))
            {
                ns.Close();
                client.Close();
                OnError(Errors.FileOpenError, "不存在的文件:" + lanFile.Path, file, null);
                return;
            }

            LoggerFactory.Debug("open file");
            FileStream fs = null;

            try
            {
                fs = new FileStream(lanFile.Path, FileMode.Open, FileAccess.Read);
                //TODO 对于大文件用MemoryMappedFile提高速度,但是对这个类用法不是很清楚,效率也未做实验,暂时不对应
                //MemoryMappedFile f1s = MemoryMappedFile.CreateFromFile(fs, FileMode.Open, "", 1024, MemoryMappedFileAccess.Read);
                //f1s.CreateViewStream
            }
            catch (Exception e)
            {
                ns.Close();
                client.Close();
                OnError(Errors.FileOpenError, "文件打开失败", file, e);
                return;
            }

            LoggerFactory.Debug("sending file");
            try
            {
                //发送文件
                file.StartTransport();
                long lastProgressTicks = file.NowTransportTicks;

                while ((len = fs.Read(buff, 0, buff.Length)) != 0)
                {
                    ns.Write(buff, 0, len);

                    file.Transported(len);

                    if (file.TransportedLength == file.File.Length ||
                        (DateTime.Now.Ticks - lastProgressTicks) > this._progressChangeInterval)     //避免进度太频繁,500ms一次
                    {
                        OnProgressChanged(file);
                        lastProgressTicks = file.NowTransportTicks;
                    }
                }
            }
            catch (Exception e)
            {
                OnError(Errors.NetworkError, "文件传输网络错误", file, e);
            }
            finally
            {
                fs.Close();

                ns.Flush();
                ns.Close();
                client.Close();

                OnCompleted(file);
            }
            LoggerFactory.Debug("end send file");
        }
示例#4
0
        public void Receive(TransportFile file)
        {
            TaskFactory taskFactory = new TaskFactory();

            taskFactory.StartNew(() =>
            {
                LoggerFactory.Debug("start receive file:id={0}", file.ID);
                string tmpPath = file.SavePath + "." + Path.GetRandomFileName().Replace(".", "") + ".lamim";
                FileStream fs  = null;
                try
                {
                    fs = new FileStream(tmpPath, FileMode.Create);
                }
                catch (Exception e)
                {
                    OnError(Errors.FileOpenError, "打开文件失败:" + tmpPath, file, e);
                    return;
                }
                LoggerFactory.Debug("opened file:" + tmpPath);

                LoggerFactory.Debug("try connect remote:remote={0}, port={1}", file.Remote, file.Port);
                TcpClient tcpClient = null;
                NetworkStream ns    = null;
                try
                {
                    tcpClient = new TcpClient(AddressFamily.InterNetwork)
                    {
                        ReceiveBufferSize = this.ReceiveBufferSize
                    };

                    tcpClient.Connect(file.Remote, file.Port);

                    ns = tcpClient.GetStream();
                }
                catch (Exception e)
                {
                    OnError(Errors.NetworkError, "连接失败", file, e);
                    return;
                }
                LoggerFactory.Debug("conneted remote:remote={0}, port={1}", file.Remote, file.Port);

                LoggerFactory.Debug("encode packet, request file:id={0}", file.ID);
                TcpPacket packet    = null;
                EncodeResult result = null;
                try
                {
                    //发送要接受的文件ID
                    TcpPacketRequestFileTransportExtend extend = new TcpPacketRequestFileTransportExtend
                    {
                        EncryptKey = file.PublicKey,
                        FileID     = file.ID
                    };

                    packet = new TcpPacket
                    {
                        Command = TcpPacket.CMD_REQUEST_FILE_TRANSPORT,
                        Extend  = extend
                    };

                    IPacketEncoder encoder = PacketEncoderFactory.CreateEncoder(packet);
                    result = encoder.Encode(null);
                }
                catch (Exception e)
                {
                    OnError(Errors.EncodeError, "请求文件ID包加密失败。" + packet.ToString(), file, e);
                    return;
                }

                LoggerFactory.Debug("send packet, request file:id={0}", file.ID);
                try
                {
                    ns.Write(result.Fragments[0], 0, result.Fragments[0].Length);
                }
                catch (Exception e)
                {
                    OnError(Errors.NetworkError, "请求文件ID包发送失败", file, e);
                    return;
                }

                LoggerFactory.Debug("receive file start:id={0}", file.ID);
                try
                {
                    int len = 0;
                    file.StartTransport();
                    long lastProgressTicks = file.NowTransportTicks;

                    byte[] buff = new byte[this.ReceiveBufferSize];
                    while ((len = ns.Read(buff, 0, buff.Length)) != 0)
                    {
                        fs.Write(buff, 0, len);

                        file.Transported(len);

                        if (file.TransportedLength == file.File.Length ||
                            (DateTime.Now.Ticks - lastProgressTicks) > this._progressChangeInterval) //避免进度太频繁,500ms一次
                        {
                            OnProgressChanged(file);
                            lastProgressTicks = file.NowTransportTicks;
                        }
                    }
                    LoggerFactory.Debug("receive file end:id={0}", file.ID);
                }
                catch (Exception e)
                {
                    OnError(Errors.NetworkError, "文件接收失败", file, e);
                }
                finally
                {
                    LoggerFactory.Debug("close connect and save file:id={0}", file.ID);
                    //关闭连接
                    ns.Close();
                    tcpClient.Close();

                    fs.Flush(true);
                    fs.Close();

                    if (LanFile.Rename(tmpPath, file.SavePath))
                    {
                        //发送接收完毕
                        OnCompleted(file);
                    }
                    else
                    {
                        OnError(Errors.FileWriteError, "文件写入失败", file, null);
                    }
                }
                LoggerFactory.Debug("end receive file:id={0}", file.ID);
            });
        }