예제 #1
0
파일: UdpClientEx.cs 프로젝트: prape/LanIM
        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);
            }
        }