Exemple #1
0
        //向客户端发送数据
        public void Send(TcpClientEx tcpClient, ArraySegment <byte> datas)
        {
            if (tcpClient != null && tcpClient.Connected)
            {
                try
                {
                    NetworkStream stream = tcpClient.GetStream();
                    if (stream != null)
                    {
                        int num = 0;
                        while (!stream.CanWrite && tcpClient != null && tcpClient.Connected)
                        {
                            num++;
                            if (num > 10)
                            {
                                return;
                            }
                            Thread.Sleep(1000);
                            continue;
                        }
                        SplitPakeage splitPakeage = new SplitPakeage();
                        byte[]       newData      = splitPakeage.AssembleBytes(datas, this);

                        stream.WriteAsync(newData, 0, newData.Length);
                        stream.Flush();

                        TcpPackConfig.SendDelayTime();
                    }
                }
                catch { }
            }
        }
Exemple #2
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);
        }