private void SendUpdateStatePacket(UpdateState state, User user, IPAddress brdIp) { UdpPacket packet = new UdpPacket(); packet.Address = user.Address; packet.Port = user.Port; packet.ToMAC = ""; packet.FromMAC = user.ID; packet.Command = UdpPacket.CMD_STATE; UdpPacketUserStateExtend entryExtend = new UdpPacketUserStateExtend(); entryExtend.User = user; entryExtend.UpdateState = state; packet.Extend = entryExtend; UdpPacket packetWrap = new UdpPacket(); packetWrap.Address = brdIp; packetWrap.Port = this.Port; packetWrap.ToMAC = ""; packetWrap.FromMAC = this.MAC; packetWrap.Command = UdpPacket.CMD_RETRANSMIT; IPacketEncoder encoder = PacketEncoderFactory.CreateEncoder(packet); EncodeResult result = encoder.Encode(); UdpPacketRetransExtend extend = new UdpPacketRetransExtend(result.Fragments[0]); packetWrap.Extend = extend; _client.Send(packetWrap); }
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); }); }
public void Send(UdpPacket packet) { if (this._state != ClientState.Working) { return; } //异步发送 IPEndPoint remoteIpEp = new IPEndPoint(packet.Address, packet.Port); packet.GenerateID(); LoggerFactory.Debug("parepare send packet:{0}", packet); EncodeResult result = null; try { IPacketEncoder encoder = PacketEncoderFactory.CreateEncoder(packet); LoggerFactory.Debug("get encoder:{0}", encoder.GetType().Name); result = encoder.Encode(null); LoggerFactory.Debug("encode packet:{0}", result); if (result.Length > UDP_MAX_BUF_SIZE) { //超过大小的分包处理 MultiUdpPacket mpacket = new MultiUdpPacket(result.Fragments[0]); mpacket.ID = packet.ID; mpacket.ParentID = packet.ID; encoder = PacketEncoderFactory.CreateEncoder(mpacket); LoggerFactory.Debug("get encoder:{0}", encoder.GetType().Name); result = encoder.Encode(UDP_MAX_BUF_SIZE - MultiUdpPacket.HEAD_SIZE); LoggerFactory.Debug("encode packet:{0}", result); } } catch (Exception e) { OnSendPackage(packet, false); OnError(Errors.EncodeError, "加密包错误。", e); } try { for (int i = 0; i < result.Fragments.Count; i++) { byte[] buf = result.Fragments[i]; SendState state = new SendState(); state.LastPacket = i == result.Fragments.Count - 1; state.Packet = packet; _client.BeginSend(buf, buf.Length, remoteIpEp, new AsyncCallback(AsyncSendHandler), state); Thread.Sleep(20);//稍微等待一下,避免丢包 } } catch (Exception e) { OnSendPackage(packet, false); OnError(Errors.NetworkError, "发送包错误。", e); } }