Esempio n. 1
0
 public override void ConnectToServer()
 {
     if (CanConnect)
     {
         CanConnect = false;
         _tcpClient.AutoReconnect = EnableAutoReconnect;
         _tcpClient.ConnectAsync("127.0.0.1", _serverPort, (isConnected) =>
         {
             CanConnect = !isConnected;
         });
     }
 }
        private void _server_ClientStatusChanged(object sender, ClientStatusChangedEventArgs args)
        {
            if (!IsRunning)
            {
                return;
            }
            long proxyClientID = args.ClientID;

            if (args.Status == ClientStatus.Connected)
            {
                TcpClientEx tcpClient = new TcpClientEx(RawPacketSpliter.Default);
                tcpClient.Tag = proxyClientID;
                tcpClient.ClientStatusChanged += TcpClient_ClientStatusChanged;
                tcpClient.MessageReceived     += TcpClient_MessageReceived;
                tcpClient.ConnectAsync(RemoteIP, (ushort)RemotePort, (isConnected) =>
                {
                    if (isConnected)
                    {
                        bool isOK = _clientDict.TryAdd(proxyClientID, tcpClient);
                        System.Diagnostics.Debug.Assert(isOK, "add new client failed");
                    }
                    else
                    {
                        _server.CloseClient(proxyClientID);
                    }
                    if (_waitConnDict.ContainsKey(proxyClientID))
                    {
                        _waitConnDict[proxyClientID].Set();
                    }
                });
            }
            else if (args.Status == ClientStatus.Closed)
            {
                if (_clientDict.TryRemove(proxyClientID, out TcpClientEx client))
                {
                    client.Close();
                }
            }
            ClientCount = _server.Clients.Count;
            if (ClientCountChanged != null)
            {
                ClientCountChangedEventArgs countChangedArgs = new ClientCountChangedEventArgs()
                {
                    NewCount = ClientCount
                };
                ClientCountChanged(this, countChangedArgs);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Runs the client connection asynchronously.
        /// </summary>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task RunAsync()
        {
            ///尝试重新连接
            bool isReconnected = true;
            int  reconnectTry  = -1;

            do
            {
                reconnectTry++;
                ByteBuffer = new ByteBuffer();
                if (ServerTcpClient != null)
                {
                    // Take accepted connection from listener
                    tcpClient = ServerTcpClient;
                }
                else
                {
                    // Try to connect to remote host
                    var connectTimeout = TimeSpan.FromTicks(ConnectTimeout.Ticks + (MaxConnectTimeout.Ticks - ConnectTimeout.Ticks) / 20 * Math.Min(reconnectTry, 20));
                    tcpClient = new TcpClientEx(AddressFamily.InterNetwork);
                    tcpClient.ReceiveTimeout    = TcpPackConfig.ReceiveTimeout;
                    tcpClient.SendTimeout       = TcpPackConfig.SendTimeout;
                    tcpClient.SendBufferSize    = TcpPackConfig.SendBufferSize;
                    tcpClient.ReceiveBufferSize = TcpPackConfig.ReceiveBufferSize;


                    Message?.Invoke(this, new AsyncTcpEventArgs("准备连接到服务器" + IPAddress.ToString()));
                    Task connectTask;
                    if (!string.IsNullOrWhiteSpace(HostName))
                    {
                        connectTask = tcpClient.ConnectAsync(HostName, Port);
                    }
                    else
                    {
                        connectTask = tcpClient.ConnectAsync(IPAddress, Port);
                    }
                    var timeoutTask = Task.Delay(connectTimeout);
                    if (await Task.WhenAny(connectTask, timeoutTask) == timeoutTask)
                    {
                        //此处增加一个连接超时的任务
                        Message?.Invoke(this, new AsyncTcpEventArgs("连接超时"));
                        OnConnectedTimeout(isReconnected);//连接超时的返回

                        continue;
                    }
                    try
                    {
                        await connectTask;
                    }
                    catch (Exception ex)
                    {
                        Message?.Invoke(this, new AsyncTcpEventArgs("连接到远程主机时出错", ex));
                        await timeoutTask;
                        continue;
                    }
                }
                reconnectTry = -1;
                stream       = tcpClient.GetStream();


                // 读取直到连接关闭。
                //只有在读取时才能检测到闭合连接,因此我们需要读取
                //永久地,不仅仅是当我们可能使用接收到的数据时。
                var networkReadTask = Task.Run(async() =>
                {
                    // 10 KiB should be enough for every Ethernet packet
                    byte[] buffer = new byte[TcpPackConfig.ByteBufferCapacity];
                    while (true)
                    {
                        int readLength;


                        try
                        {
                            //异步读取有问题
                            readLength = await stream.ReadAsync(buffer, 0, buffer.Length);
                        }
                        catch (IOException ex) when((ex.InnerException as SocketException)?.ErrorCode == (int)SocketError.OperationAborted)
                        {
                            // Warning: This error code number (995) may change
                            Message?.Invoke(this, new AsyncTcpEventArgs("本地关闭连接", ex));
                            readLength = -1;
                        }
                        catch (IOException ex) when((ex.InnerException as SocketException)?.ErrorCode == (int)SocketError.ConnectionAborted)
                        {
                            Message?.Invoke(this, new AsyncTcpEventArgs("连接失败", ex));
                            readLength = -1;
                        }
                        catch (IOException ex) when((ex.InnerException as SocketException)?.ErrorCode == (int)SocketError.ConnectionReset)
                        {
                            Message?.Invoke(this, new AsyncTcpEventArgs("远程重置连接", ex));
                            readLength = -2;
                        }
                        if (readLength <= 0)
                        {
                            if (readLength == 0)
                            {
                                Message?.Invoke(this, new AsyncTcpEventArgs("远程关闭连接"));
                            }
                            closedTcs.TrySetResult(true);
                            OnClosed(readLength != -1);
                            return;
                        }
                        //此处做处理,数据包要达到
                        var segment = new ArraySegment <byte>(buffer, 0, readLength);
                        ByteBuffer.Enqueue(segment);
                        await OnReceivedAsync(readLength);
                    }
                });

                closedTcs = new TaskCompletionSource <bool>();
                await OnConnectedAsync(isReconnected);

                // Wait for closed connection
                await networkReadTask;
                tcpClient.Close();

                isReconnected = true;
            }while (AutoReconnect && ServerTcpClient == null);
        }