Beispiel #1
0
        private void EndAccept(SocketAsyncEventArgs args)
        {
            using (_Trace.Open())
            {
                Socket client = null;
                try
                {
                    if (args.SocketError != SocketError.Success)
                    {
                        throw new SocketException((int)args.SocketError);
                    }
                    client = args.AcceptSocket;
                    if (_Cancel.IsCancellationRequested)
                    {
                        return;
                    }
                    NodeServerTrace.Information("Client connection accepted : " + client.RemoteEndPoint);
                    var cancel = CancellationTokenSource.CreateLinkedTokenSource(_Cancel.Token);
                    cancel.CancelAfter(TimeSpan.FromSeconds(10));

                    var stream = new NetworkStream(client, false);
                    while (true)
                    {
                        cancel.Token.ThrowIfCancellationRequested();
                        PerformanceCounter counter;
                        var message = Message.ReadNext(stream, Network, Version, cancel.Token, out counter);
                        _MessageProducer.PushMessage(new IncomingMessage()
                        {
                            Socket  = client,
                            Message = message,
                            Length  = counter.ReadenBytes,
                            Node    = null,
                        });
                        if (message.Payload is VersionPayload)
                        {
                            break;
                        }
                        else
                        {
                            NodeServerTrace.Error("The first message of the remote peer did not contained a Version payload", null);
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    Utils.SafeCloseSocket(client);
                    if (!_Cancel.Token.IsCancellationRequested)
                    {
                        NodeServerTrace.Error("The remote connecting failed to send a message within 10 seconds, dropping connection", null);
                    }
                }
                catch (Exception ex)
                {
                    if (_Cancel.IsCancellationRequested)
                    {
                        return;
                    }
                    if (client == null)
                    {
                        NodeServerTrace.Error("Error while accepting connection ", ex);
                        Thread.Sleep(3000);
                    }
                    else
                    {
                        Utils.SafeCloseSocket(client);
                        NodeServerTrace.Error("Invalid message received from the remote connecting node", ex);
                    }
                }
                BeginAccept();
            }
        }
Beispiel #2
0
        internal void StartConnecting()
        {
            if (_Disconnect.IsCancellationRequested)
            {
                return;
            }
            if (_ConnectedNodes.Count >= MaximumNodeConnection)
            {
                return;
            }
            if (_Connecting)
            {
                return;
            }
            Task.Factory.StartNew(() =>
            {
                if (Monitor.TryEnter(cs))
                {
                    _Connecting = true;
                    TraceCorrelationScope scope = null;
                    try
                    {
                        while (!_Disconnect.IsCancellationRequested && _ConnectedNodes.Count < MaximumNodeConnection)
                        {
                            scope = scope ?? _Trace.Open();

                            NodeServerTrace.Information("Connected nodes : " + _ConnectedNodes.Count + "/" + MaximumNodeConnection);
                            var parameters = _ConnectionParameters.Clone();
                            parameters.TemplateBehaviors.Add(new NodesGroupBehavior(this));
                            parameters.ConnectCancellation = _Disconnect.Token;
                            var addrman = AddressManagerBehavior.GetAddrman(parameters);

                            if (addrman == null)
                            {
                                addrman = _DefaultAddressManager;
                                AddressManagerBehavior.SetAddrman(parameters, addrman);
                            }

                            Node node = null;
                            try
                            {
                                node        = Node.Connect(_Network, parameters, AllowSameGroup ? null : _ConnectedNodes.Select(n => n.RemoteSocketAddress).ToArray());
                                var timeout = CancellationTokenSource.CreateLinkedTokenSource(_Disconnect.Token);
                                timeout.CancelAfter(5000);
                                node.VersionHandshake(_Requirements, timeout.Token);
                                NodeServerTrace.Information("Node successfully connected to and handshaked");
                            }
                            catch (OperationCanceledException ex)
                            {
                                if (_Disconnect.Token.IsCancellationRequested)
                                {
                                    throw;
                                }
                                NodeServerTrace.Error("Timeout for picked node", ex);
                                if (node != null)
                                {
                                    node.DisconnectAsync("Handshake timeout", ex);
                                }
                            }
                            catch (Exception ex)
                            {
                                NodeServerTrace.Error("Error while connecting to node", ex);
                                if (node != null)
                                {
                                    node.DisconnectAsync("Error while connecting", ex);
                                }
                            }
                        }
                    }
                    finally
                    {
                        Monitor.Exit(cs);
                        _Connecting = false;
                        if (scope != null)
                        {
                            scope.Dispose();
                        }
                    }
                }
            }, TaskCreationOptions.LongRunning);
        }