Пример #1
0
        public void Update()
        {
            if (socket.Poll(0, SelectMode.SelectRead))
            {
                int read = 0;
                buffer.SetSize(MAX_PACKET_SIZE);                 // This should just reset the internal size to MAX_PACKET_SIZE
                buffer.ResetPointer();
                try
                {
                    read = socket.ReceiveFrom(buffer.byteArr, buffer.byteArr.Length, SocketFlags.None,
                                              ref endpoint);
                }
                catch (SocketException e)
                {
                    // If the exception was a connection reset then ignore it otherwise rethrow it.
                    if (e.SocketErrorCode != SocketError.ConnectionReset)
                    {
                        throw;
                    }
                }

                if (read > 0)
                {
                    var header = new QueryHeader();
                    header.Deserialize(buffer);

                    buffer.ResetPointer();
                    foreach (var query in Queries)
                    {
                        if (query.Server == null || !endpoint.Equals(query.Server))
                        {
                            continue;
                        }

                        switch (query.State)
                        {
                        case ClientState.Idle:
                            break;

                        case ClientState.WaitingForChallange:
                            if ((MessageType)header.Type == MessageType.ChallengeResponse)
                            {
                                query.ChallengeId = header.ChallengeId;
                                query.RTT         = SQPClient.stopwatch.ElapsedMilliseconds - query.StartTime;
                                query.StartTime   = SQPClient.stopwatch.ElapsedMilliseconds;
                                SendServerInfoQuery(query);
                            }
                            break;

                        case ClientState.WaitingForResponse:
                            if ((MessageType)header.Type == MessageType.QueryResponse)
                            {
                                query.ServerInfo.Deserialize(buffer);

                                query.RTT =
                                    (query.RTT + (SQPClient.stopwatch.ElapsedMilliseconds - query.StartTime)) / 2;

                                query.ValidResult = true;
                                query.State       = ClientState.Idle;
                            }

                            break;

                        default:
                            break;
                        }
                    }
                }
            }

            foreach (var query in Queries)
            {
                if (query.State != ClientState.Idle)
                {
                    var now = SQPClient.stopwatch.ElapsedMilliseconds;

                    // If we have not received anything from a server then let's reset it's state to Idle
                    if (now - query.StartTime > QUERY_TIMEOUT)
                    {
                        query.State       = ClientState.Idle;
                        query.ValidResult = false;
                    }
                }
            }
        }
Пример #2
0
        public void Update()
        {
            if (socket.Poll(0, SelectMode.SelectRead))
            {
                buffer.SetSize(MAX_PACKET_SIZE);
                buffer.ResetPointer();
                int read = socket.ReceiveFrom(buffer.byteArr, buffer.byteArr.Length, SocketFlags.None, ref endpoint);
                if (read > 0)
                {
                    var header = new QueryHeader();
                    header.Deserialize(buffer);

                    var type = (MessageType)header.Type;

                    switch (type)
                    {
                    case MessageType.ChallengeRequest:
                    {
                        if (!outstandingTokens.ContainsKey(endpoint))
                        {
                            buffer.Clear();
                            // Issue a challenge token to this endpoint
                            uint token = GetNextToken();

                            var response = new ChallengeResponse();
                            response.Header.ChallengeId = token;
                            response.Serialize(ref buffer);

                            var data = buffer.CompressBytes();
                            socket.SendTo(data, data.Length, SocketFlags.None, endpoint);

                            outstandingTokens.Add(endpoint, token);
                        }
                    }
                    break;

                    case MessageType.QueryRequest:
                    {
                        uint token;
                        if (!outstandingTokens.TryGetValue(endpoint, out token))
                        {
                            return;
                        }

                        outstandingTokens.Remove(endpoint);

                        buffer.ResetPointer();
                        var request = new QueryRequest();
                        request.Deserialize(buffer);

                        if (request.Header.ChallengeId != token)
                        {
                            return;
                        }

                        if ((ChunkType)request.RequestedChunks == ChunkType.ServerInfo)
                        {
                            var response = serverInfo;
                            response.QueryHeader.Header.ChallengeId = token;

                            buffer.Clear();
                            response.Serialize(ref buffer);
                            var data = buffer.CompressBytes();
                            socket.SendTo(data, data.Length, SocketFlags.None, endpoint);
                        }
                    }
                    break;

                    default:
                        break;
                    }
                }
            }
        }