コード例 #1
0
        private void PrimeConnection(TcpClient client)
        {
            LOG.Info(string.Format("Socket connection established to {0}, initiating session", client.Client.RemoteEndPoint));

            ConnectRequest conReq = new ConnectRequest(0, lastZxid, Convert.ToInt32(conn.SessionTimeout.TotalMilliseconds), conn.SessionId, conn.SessionPassword);

            byte[] buffer;
            using (MemoryStream ms = new MemoryStream())
                using (EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Big, ms, Encoding.UTF8))
                {
                    BinaryOutputArchive boa = BinaryOutputArchive.getArchive(writer);
                    boa.WriteInt(-1, "len");
                    conReq.Serialize(boa, "connect");
                    ms.Position = 0;
                    writer.Write(ms.ToArray().Length - 4);
                    buffer = ms.ToArray();
                }
            lock (outgoingQueueLock)
            {
                if (!ClientConnection.disableAutoWatchReset && (!zooKeeper.DataWatches.IsEmpty() || !zooKeeper.ExistWatches.IsEmpty() || !zooKeeper.ChildWatches.IsEmpty()))
                {
                    var sw = new SetWatches(lastZxid, zooKeeper.DataWatches, zooKeeper.ExistWatches, zooKeeper.ChildWatches);
                    var h  = new RequestHeader();
                    h.Type = (int)OpCode.SetWatches;
                    h.Xid  = -8;
                    Packet packet = new Packet(h, new ReplyHeader(), sw, null, null, null, null, null);
                    outgoingQueue.AddFirst(packet);
                }

                foreach (ClientConnection.AuthData id in conn.authInfo)
                {
                    outgoingQueue.AddFirst(new Packet(new RequestHeader(-4, (int)OpCode.Auth), null, new AuthPacket(0, id.scheme, id.data), null, null, null, null, null));
                }
                outgoingQueue.AddFirst((new Packet(null, null, null, null, buffer, null, null, null)));
            }

            lock (this)
            {
                EnableWrite();
            }

            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Session establishment request sent on " + client.Client.RemoteEndPoint);
            }
        }
コード例 #2
0
ファイル: Client.cs プロジェクト: gmriggs/ACE.Diag
        /// <summary>
        /// Connect to a server ip address
        /// </summary>
        /// <returns>Connection success</returns>
        public bool Connect(string ip)
        {
            Console.WriteLine("Connecting to " + ip);

            UdpClient = new UdpClient(ClientPort);
            Endpoint  = new IPEndPoint(IPAddress.Parse(ip), Server.DefaultPort);

            // connect to server
            UdpClient.Connect(Endpoint);

            // send connect request
            var connectRequest = new ConnectRequest();
            var data           = connectRequest.Serialize();

            UdpClient.Send(data, data.Length);

            // wait for response
            byte[] responseBytes = null;
            try
            {
                responseBytes = UdpClient.Receive(ref Endpoint);
            }
            catch (Exception)
            {
                //Console.WriteLine(e);
                Console.WriteLine("Couldn't connect to server");
                return(false);
            }
            ShowResponse(responseBytes);

            // deserialize response packet
            var packet = GetPacket(responseBytes);

            if (packet.Type == PacketType.ConnectResponse)
            {
                var responsePacket = (ConnectResponse)packet;
                if (responsePacket.ConnectResponseType != ConnectResponseType.Accepted || !responsePacket.Reason.Equals("ok"))
                {
                    Console.WriteLine("Connection refused");
                    return(false);
                }
            }
            else if (packet.Type == PacketType.PingRequest)
            {
                var pingRequest = (PingRequest)packet;

                // craft a ping response with matching info
                // this small handshake should hopefully prevent ip spoofing / amplification
                // before the larger packets are sent for world state
                var pingResponse      = new PingResponse(pingRequest);
                var pingResponseBytes = pingResponse.Serialize();
                UdpClient.Send(pingResponseBytes, pingResponseBytes.Length);

                // wait for world data
                responseBytes = UdpClient.Receive(ref Endpoint);
                //ShowResponse(responseBytes);
                var gameState = (Packet.GameState)GetPacket(responseBytes);
                GameState = gameState.State;

                Console.WriteLine(string.Format("Connected to {0}:{1}", ip, Server.DefaultPort));
                IsConnected = true;

                // start receiving async
                UdpClient.BeginReceive(ReceiveData, UdpClient);
            }
            else
            {
                Console.WriteLine("Unknown connection response: " + packet.Type);
                return(false);
            }

            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NamedPipeClient" /> class.
        /// </summary>
        /// <param name="description">The client description.</param>
        /// <param name="server">The server.</param>
        /// <param name="onReceive">The action to call on receipt of a message.</param>
        /// <param name="token">The token.</param>
        private NamedPipeClient(
            [NotNull] string description,
            [NotNull] NamedPipeServerInfo server,
            [NotNull] Action <Message> onReceive,
            CancellationToken token = default(CancellationToken))
        {
            if (description == null)
            {
                throw new ArgumentNullException("description");
            }
            if (server == null)
            {
                throw new ArgumentNullException("server");
            }
            if (onReceive == null)
            {
                throw new ArgumentNullException("onReceive");
            }

            _server = server;

            _cancellationTokenSource = new CancellationTokenSource();
            CancellationToken disposeToken = _cancellationTokenSource.Token;

            _clientTask = Task.Run(
                async() =>
            {
                try
                {
                    using (ITokenSource tokenSource = token.CreateLinked(disposeToken))
                        using (
                            OverlappingPipeClientStream stream = new OverlappingPipeClientStream(
                                _server.Host,
                                _server.FullName,
                                PipeTransmissionMode.Message))
                        {
                            _state = PipeState.Open;

                            token = tokenSource.Token;

                            // We need to support cancelling the connect.
                            await stream.Connect(token).ConfigureAwait(false);

                            ConnectResponse connectResponse       = null;
                            DisconnectResponse disconnectResponse = null;

                            if (!token.IsCancellationRequested)
                            {
                                // Set the stream.
                                _stream = stream;
                                _state  = PipeState.AwaitingConnect;

                                // Kick off a connect request, but don't wait for it's result as we're the task that will receive it!
                                ConnectRequest connectRequest = new ConnectRequest(description);
                                await stream.WriteAsync(connectRequest.Serialize(), token).ConfigureAwait(false);

                                // Keep going as long as we're connected.
                                try
                                {
                                    while (stream.IsConnected &&
                                           !disposeToken.IsCancellationRequested)
                                    {
                                        // Read data in.
                                        byte[] data = await stream.ReadAsync(disposeToken).ConfigureAwait(false);

                                        if (data == null)
                                        {
                                            break;
                                        }

                                        // Deserialize the incoming message.
                                        Message message = Message.Deserialize(data);

                                        if (connectResponse == null)
                                        {
                                            // We require a connect response to start
                                            connectResponse = message as ConnectResponse;
                                            if (connectResponse == null ||
                                                connectResponse.ID != connectRequest.ID)
                                            {
                                                break;
                                            }

                                            _state       = PipeState.Connected;
                                            _serviceName = connectResponse.ServiceName;

                                            Log.Add(
                                                LoggingLevel.Notification,
                                                () => ClientResources.Not_NamedPipeClient_Connection,
                                                connectResponse.ServiceName);

                                            TaskCompletionSource <NamedPipeClient> ccs =
                                                Interlocked.Exchange(ref _connectionCompletionSource, null);
                                            if (ccs != null)
                                            {
                                                ccs.TrySetResult(this);
                                            }

                                            // Observer the message.
                                            onReceive(message);
                                            continue;
                                        }

                                        // Check for disconnect, we don't observe the message until the disconnect is complete.
                                        disconnectResponse = message as DisconnectResponse;
                                        if (disconnectResponse != null)
                                        {
                                            break;
                                        }

                                        // Observe the message.
                                        onReceive(message);

                                        Response response = message as Response;
                                        if (response == null)
                                        {
                                            continue;
                                        }

                                        ConnectedCommand connectedCommand;

                                        // Check for cancellation responses.
                                        CommandCancelResponse cancelResponse = response as CommandCancelResponse;
                                        if (cancelResponse != null)
                                        {
                                            // Cancel the associated request
                                            if (_commandRequests.TryGetValue(
                                                    cancelResponse.CancelledCommandId,
                                                    out connectedCommand))
                                            {
                                                // ReSharper disable once PossibleNullReferenceException
                                                connectedCommand.Cancel(cancelResponse);
                                            }
                                        }

                                        // And fall through to complete the response...

                                        // Find command the response is related to, and notify it of the response.
                                        if (!_commandRequests.TryGetValue(response.ID, out connectedCommand))
                                        {
                                            continue;
                                        }

                                        Debug.Assert(connectedCommand != null);
                                        if (connectedCommand.Received(response))
                                        {
                                            _commandRequests.TryRemove(response.ID, out connectedCommand);
                                        }
                                    }
                                }
                                catch (TaskCanceledException)
                                {
                                }
                            }

                            // If we're still connected, and we haven't received a disconnect response, try to send a disconnect request.
                            if (stream.IsConnected &&
                                disconnectResponse == null)
                            {
                                CancellationTokenSource cts = token.IsCancellationRequested
                                    ? new CancellationTokenSource(500)
                                    : null;
                                try
                                {
                                    CancellationToken t = cts != null
                                        ? cts.Token
                                        : token;

                                    // Try to send disconnect request.
                                    // ReSharper disable once PossibleNullReferenceException
                                    await Send(new DisconnectRequest(), t)
                                    .ToTask(t)
                                    .ConfigureAwait(false);
                                }
                                catch (TaskCanceledException)
                                {
                                }
                                finally
                                {
                                    if (cts != null)
                                    {
                                        cts.Dispose();
                                    }
                                }
                            }

                            // Remove the stream.
                            _stream      = null;
                            _state       = PipeState.Closed;
                            _serviceName = null;

                            // If we had a disconnect message observe it now that the disconnect has been actioned,
                            // this prevents the receiver thinking the connection is still active.
                            if (disconnectResponse != null)
                            {
                                onReceive(disconnectResponse);
                                ConnectedCommand connectedCommand;
                                if (_commandRequests.TryGetValue(disconnectResponse.ID, out connectedCommand))
                                {
                                    Debug.Assert(connectedCommand != null);
                                    if (connectedCommand.Received(disconnectResponse))
                                    {
                                        _commandRequests.TryRemove(disconnectResponse.ID, out connectedCommand);
                                    }
                                }
                            }
                        }
                }
                catch (IOException ioe)
                {
                    if (!token.IsCancellationRequested)
                    {
                        // Common exception caused by sudden disconnect, lower level
                        Log.Add(
                            ioe,
                            LoggingLevel.Information,
                            () => ClientResources.Err_NamedPipeClient_Failed);
                    }
                }
                catch (Exception exception)
                {
                    TaskCanceledException tce = exception as TaskCanceledException;
                    TaskCompletionSource <NamedPipeClient> ccs = Interlocked.Exchange(
                        ref _connectionCompletionSource,
                        null);
                    if (ccs != null)
                    {
                        if (tce != null)
                        {
                            ccs.TrySetCanceled();
                        }
                        else
                        {
                            ccs.TrySetException(exception);
                        }
                    }

                    // We only log if this wasn't a cancellation exception.
                    if (tce == null &&
                        !token.IsCancellationRequested)
                    {
                        Log.Add(
                            exception,
                            LoggingLevel.Error,
                            () => ClientResources.Err_NamedPipeClient_Failed);
                    }
                }
                finally
                {
                    Dispose();
                }
            },
                disposeToken);
        }