Esempio n. 1
0
        /** <summary>Reader thread.</summary> */
        private void readPackets()
        {
            try {
                bool   running = true;
                byte[] lenByte = new byte[4];
                byte[] head    = new byte[40];

                while (running)
                {
                    // Note that only this thread removes futures from map.
                    // So if we see closed condition, it is safe to check map size since no more futures
                    // will be added to the map.
                    if (closed)
                    {
                        // Exit if either all requests processed or we do not wait for completion.
                        if (!waitCompletion)
                        {
                            break;
                        }

                        if (pendingReqs.Count == 0)
                        {
                            break;
                        }
                    }

                    // Header.
                    int symbol;

                    try {
                        if (lastReadTimedOut)
                        {
                            lastReadTimedOut = false;

                            if (isSslStream)
                            {
                                // Recover SSL stream state after socket exception.
                                skipSslDataRecordHeader();
                            }
                        }

                        symbol = inStream.ReadByte();
                    }
                    catch (Exception e) {
                        if (e.InnerException is SocketException)
                        {
                            e = e.InnerException;
                        }

                        var sockEx = e as SocketException;

                        if (sockEx != null && sockEx.ErrorCode == 10060)
                        {
                            checkPing();

                            lastReadTimedOut = true;

                            continue;
                        }

                        // All other exceptions are interpreted as stream ends.
                        throw;
                    }

                    // Connection closed.
                    if (symbol == -1)
                    {
                        Dbg.WriteLine("Connection closed by remote host " +
                                      "[srvAddr=" + ServerAddress + ", symbol=" + symbol + "]");

                        break;
                    }

                    // Check for correct header.
                    if ((byte)symbol != (byte)0x90)
                    {
                        Dbg.WriteLine("Failed to parse incoming message (unexpected header received, will close) " +
                                      "[srvAddr=" + ServerAddress + ", symbol=" + symbol + "]");

                        break;
                    }

                    U.ReadFully(inStream, lenByte, 0, 4);

                    int len = U.BytesToInt32(lenByte, 0);

                    if (len == 0)
                    {
                        // Ping received.
                        lastPingRcvTime = U.Now;

                        continue;
                    }

                    if (len < 40)
                    {
                        Dbg.WriteLine("Invalid packet received [len=" + len + "]");

                        break;
                    }

                    U.ReadFully(inStream, head, 0, 40);

                    long reqId      = U.BytesToInt64(head, 0);
                    Guid clientId   = U.BytesToGuid(head, 8);
                    Guid destNodeId = U.BytesToGuid(head, 24);

                    byte[] msgBytes = new byte[len - 40];

                    U.ReadFully(inStream, msgBytes, 0, msgBytes.Length);

                    GridClientResponse msg = marshaller.Unmarshal <GridClientResponse>(msgBytes);

                    msg.RequestId  = reqId;
                    msg.ClientId   = clientId;
                    msg.DestNodeId = destNodeId;

                    lastPacketRcvTime = U.Now;

                    handleResponse(msg);
                }
            }
            catch (IOException e) {
                if (!closed)
                {
                    Dbg.WriteLine("Failed to read data from remote host (will close connection)" +
                                  " [addr=" + ServerAddress + ", e=" + e.Message + "]");
                }
            }
            catch (Exception e) {
                Dbg.WriteLine("Unexpected throwable in connection reader thread (will close connection)" +
                              " [addr={0}, e={1}]", ServerAddress, e);
            }
            finally {
                U.Async(() => Close(false));
            }
        }