예제 #1
0
파일: AgNetPeer.cs 프로젝트: Agasper/AgNet
        internal bool SendMessageInternal(OutgoingMessage msg, DeliveryType deliveryType)
        {
            if (disposed)
            {
                return(false);
            }

            byte[] sendBuffer = msg.ToByteArray(deliveryType);

            try
            {
                lock (socket)
                {
                    socket.DontFragment = msg.DontFragment;
                    socket.SendTo(sendBuffer, msg.RemoteEP);
                    // TO DO: Check sent size
                }
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.ConnectionReset ||
                    ex.SocketErrorCode == SocketError.MessageSize)
                {
                    return(false);
                }
                if (ex.SocketErrorCode == SocketError.WouldBlock)
                {
                    throw new AgNetException("Socket send buffer is full. Try to expand it.");
                }
            }

            msg.LastSentTime = DateTime.UtcNow;
            msg.SentTimes++;
            msg.Status = AgNetSendStatus.Sent;

            if (deliveryType != DeliveryType.Reliable)
            {
                msg.Dispose();
            }

            return(true);
        }
예제 #2
0
        bool ProcessMessage(IAgNetChannel channel, IncomingMessage msg)
        {
            if (msg.Type == PacketType.ConfirmDelivery)
            {
                int confirmed = msg.ReadInt32();
                for (int i = 0; i < confirmed; i++)
                {
                    int             sequence    = msg.ReadInt32();
                    OutgoingMessage deliveryFor = reliableChannel.PopFromAwaitConfirmation(sequence);

                    if (deliveryFor == null)
                    {
                        continue;
                    }

                    deliveryFor.Status = AgNetSendStatus.Confirmed;

                    if (State == SessionState.Connecting && deliveryFor.Type == PacketType.ConnectAck)
                    {
                        SetState(SessionState.Connected);
                    }

                    if (State == SessionState.Closing && deliveryFor.Type == PacketType.FinResp)
                    {
                        Close("Shutdown method called");
                    }

                    deliveryFor.Dispose();
                }

                return(false);
            }

            if (msg.Type == PacketType.Ping)
            {
                Pong(msg);
                return(false);
            }

            if (msg.Type == PacketType.MTUExpandRequest)
            {
                ReceivedMtuExpand(msg);
                return(false);
            }

            if (msg.Type == PacketType.MTUSuccess)
            {
                ReceivedMtuResponse(msg);
                return(false);
            }

            if (msg.Type == PacketType.Pong)
            {
                lastPongReceived = DateTime.UtcNow;
                DateTime sent = new DateTime(msg.ReadInt64());
                TimeSpan ts   = DateTime.UtcNow - sent;
                PingRoundtrip = (int)ts.TotalMilliseconds;
                return(false);
            }

            if (msg.Type == PacketType.ConnectionError)
            {
                Close(msg.ReadString());
                return(false);
            }

            if (msg.Type == PacketType.FinAck)
            {
                SetState(SessionState.Closing);
                FinResp();
                return(false);
            }

            if (msg.Type == PacketType.FinResp)
            {
                Close("Connection closed by remote peer");
                return(false);
            }

            if (msg.Type == PacketType.ConnectAck && State == SessionState.Closed)
            {
                var server = peer as AgNetServer;
                if (server != null)
                {
                    if (server.MaximumSessions > 0 && server.SessionsCount >= server.MaximumSessions)
                    {
                        SendError("Server rejected connection");
                    }
                    else
                    {
                        SetState(SessionState.Connected);
                    }
                }
                return(false);
            }


            if (msg.Type == PacketType.Ping)
            {
                return(false);
            }

            if (msg.Type == PacketType.PartialMessage)
            {
                return(false);
            }

            if (State == SessionState.Connected && msg.Type == PacketType.UserData)
            {
                return(true);
            }

            Close("Unknown service packet");
            return(false);
        }