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); }
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"); }
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); }); }