예제 #1
0
파일: UdpClientEx.cs 프로젝트: prape/LanIM
        protected void OnPackageReceived(UdpPacket packet)
        {
            if (packet.Type == Packet.PACKTE_TYPE_MULTI_UDP)
            {
                MultiUdpPacket mp = packet as MultiUdpPacket;
                if (!_recvingPacketDic.TryGetValue(mp.ParentID, out MultiUdpPacket parentMp))
                {
                    parentMp         = new MultiUdpPacket(mp.TotalLength);
                    parentMp.ID      = mp.ParentID;
                    parentMp.Address = packet.Address;
                    parentMp.Port    = packet.Port;

                    _recvingPacketDic.TryAdd(mp.ParentID, parentMp);
                }
                parentMp.CopyFragmentBuff(mp);

                if (parentMp.TotalLength == parentMp.Length)
                {
                    //收取中缓存移除,添加到已经接受的包中
                    _recvingPacketDic.TryRemove(mp.ParentID, out MultiUdpPacket pMp);

                    IPacketResolver resolver = PacketResolverFactory.CreateResolver(pMp.FragmentBuff, 0, pMp.TotalLength, this.SecurityKeys.Private);
                    LoggerFactory.Debug("get resolver:{0}", resolver.GetType().Name);

                    UdpPacket udpPacket = resolver.Resolve() as UdpPacket;
                    udpPacket.Address = packet.Address;
                    udpPacket.Port    = packet.Port;

                    _receivedPackets.Add(udpPacket);
                }
            }
            else
            {
                _receivedPackets.Add(packet);
            }
        }
예제 #2
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");
        }
예제 #3
0
파일: UdpClientEx.cs 프로젝트: prape/LanIM
        private void AsyncReceiveHandler(IAsyncResult ar)
        {
            bool isExiting = false;

            if (ar.IsCompleted)
            {
                byte[]     buff     = null;
                IPEndPoint remoteEp = null;
                try
                {
                    buff = _client.EndReceive(ar, ref remoteEp);
                    LoggerFactory.Debug("received:{0}", buff);
                }
                catch (Exception e)
                {
                    OnError(Errors.OutofSizePacket, "收包错误。", e);
                }

                if (buff != null && buff.Length > 0)
                {
                    try
                    {
                        IPacketResolver resolver = PacketResolverFactory.CreateResolver(buff, 0, buff.Length, this.SecurityKeys.Private);
                        LoggerFactory.Debug("get resolver:{0}", resolver.GetType().Name);

                        UdpPacket packet = resolver.Resolve() as UdpPacket;
                        packet.Address = remoteEp.Address;
                        packet.Port    = remoteEp.Port;
                        LoggerFactory.Debug("resolved packet:{0}", packet);

                        OnPackageReceived(packet);

                        if (packet.Type == Packet.PACKTE_TYPE_UDP &&
                            packet.CMD == UdpPacket.CMD_EXIT &&
                            packet.Address.Equals(this.IP))
                        {
                            //如果是当前用户发出退出请求,下一步则不监听了
                            isExiting = true;
                        }
                    }
                    catch (Exception e)
                    {
                        OnError(Errors.ResolveError, "解包错误。", e);
                    }
                }
            }

            if (isExiting ||
                this._state == ClientState.Closing ||
                this._state == ClientState.Closed)
            {
                //正在准备退出
            }
            else
            {
                try
                {
                    //继续下一次收包
                    _client.BeginReceive(AsyncReceiveHandler, null);
                    LoggerFactory.Debug("begin receive");
                }
                catch (Exception e)
                {
                    OnError(Errors.OutofSizePacket, "接受消息停止,需要重新监听....", e);
                }
            }
        }