예제 #1
0
 // 接收响应包
 // 注意调用返回后如果发现出错,调主要主动 Close 和重新分配 TcpClient
 // parameters:
 //      nMaxLength  读入等待处理的 bytes 极限数字。超过了这个,还没有找到结束符,就会抛出异常。意在防范攻击。-1 表示不限制
 //      touch_func  回调函数,用于保持通道活跃
 public static async Task <RecvResult> SimpleRecvTcpPackage(TcpClient _client,
                                                            int nMaxLength,
                                                            delegate_touch touch_func = null)
 {
     return(await ZChannel.SimpleRecvTcpPackage(_client,
                                                null,
                                                (package, start, length) =>
     {
         bool bRet = BerNode.IsCompleteBER(package,
                                           start,
                                           length,
                                           out long remainder);
         if (bRet == true)
         {
             return new Tuple <int, byte>((int)remainder, 0);
         }
         return new Tuple <int, byte>(0, 0);
     },
                                                touch_func,
                                                nMaxLength).ConfigureAwait(false));
 }
예제 #2
0
파일: ZChannel.cs 프로젝트: zszqwe/dp2
        // 接收响应包
        public int RecvTcpPackage(out byte[] baPackage,
                                  out int nLen,
                                  out string strError)
        {
            strError = "";

            int  nInLen;
            int  wRet        = 0;
            bool bInitialLen = false;

            Debug.Assert(client != null, "client为空");

            baPackage = new byte[4096];
            nInLen    = 0;
            nLen      = 4096; //COMM_BUFF_LEN;

            long lIdleCount = 0;

            while (nInLen < nLen)
            {
                if (client != null)
                {
                    /*
                     * if (client.Client.Poll(-1, SelectMode.SelectError))
                     * {
                     *  strError = "通讯中断0";
                     *  goto ERROR1;
                     * }
                     *
                     *
                     * if (client.Client.Connected == false)
                     * {
                     *  strError = "通讯中断0";
                     *  goto ERROR1;
                     * }
                     * */
                }

                if (CommIdle != null &&
                    client != null &&
                    lIdleCount < 20)
                {
                    int nCount = 0;

                    try
                    {
                        nCount = client.Available;
                    }
                    catch (SocketException ex)
                    {
                        if (ex.ErrorCode == 0)
                        {
                            strError = "通讯中断0";
                            goto ERROR1;
                        }
                    }
                    if (nCount == 0)
                    {
                        CommIdleEventArgs e = new CommIdleEventArgs();
                        this.CommIdle(this, e);
                        if (e.Cancel == true)
                        {
                            strError = e.ErrorInfo;
                            goto ERROR1;
                        }
                        System.Threading.Thread.Sleep(10);
                        lIdleCount++;
                        continue;
                    }
                }

                if (client == null)
                {
                    strError = "通讯中断";
                    goto ERROR1;
                }

                try
                {
                    wRet = client.GetStream().Read(baPackage,
                                                   nInLen,
                                                   baPackage.Length - nInLen);

                    lIdleCount = 0;

                    /*
                     * wRet = client.Client.Receive(baPackage,
                     *  nInLen,
                     *  SocketFlags.None);
                     * */
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10035)
                    {
                        CommIdleEventArgs e = new CommIdleEventArgs();
                        this.CommIdle(this, e);
                        if (e.Cancel == true)
                        {
                            strError = e.ErrorInfo;
                            goto ERROR1;
                        }
                        System.Threading.Thread.Sleep(100);
                        continue;
                    }
                    strError = "recv出错: " + ex.Message;
                    goto ERROR1;
                }
                catch (Exception ex)
                {
                    strError = "recv出错: " + ex.Message;
                    goto ERROR1;
                }

                if (wRet == 0)
                {
                    strError = "Closed by remote peer";
                    goto ERROR1;
                }

                // 得到包的长度

                if ((wRet >= 1 || nInLen >= 1) &&
                    bInitialLen == false)
                {
                    long remainder = 0;
                    bool bRet      = BerNode.IsCompleteBER(baPackage,
                                                           0,
                                                           nInLen + wRet,
                                                           out remainder);
                    if (bRet == true)
                    {
                        /*
                         * // 正式分配缓冲区尺寸
                         * byte[] temp = new byte[nLen];
                         * Array.Copy(baPackage, 0, temp, 0, nInLen + wRet);
                         * baPackage = temp;
                         *
                         * bInitialLen = true;
                         * */
                        nLen = nInLen + wRet;
                        break;
                    }
                }

                nInLen += wRet;
                if (nInLen >= baPackage.Length &&
                    bInitialLen == false)
                {
                    // 扩大缓冲区
                    byte[] temp = new byte[baPackage.Length + 4096];
                    Array.Copy(baPackage, 0, temp, 0, nInLen);
                    baPackage = temp;
                    nLen      = baPackage.Length;
                }
            }

            // 最后规整缓冲区尺寸,如果必要的话
            if (baPackage.Length > nLen)
            {
                byte[] temp = new byte[nLen];
                Array.Copy(baPackage, 0, temp, 0, nLen);
                baPackage = temp;
            }

            return(0);

ERROR1:
            this.CloseSocket();
            baPackage = null;
            return(-1);
        }
예제 #3
0
파일: ZChannel.cs 프로젝트: zszqwe/dp2
        void RecvCallback(IAsyncResult ar)
        {
            try
            {
                if (client == null)
                {
                    m_strAsycError = "用户中断";
                    goto ERROR1;
                }
                Debug.Assert(client != null, "");

                // TODO: 是否要关闭 NetworkStream !!!
                NetworkStream stream = client.GetStream();
                Debug.Assert(stream != null, "");

                int nReaded = stream.EndRead(ar);
                if (nReaded == 0)
                {
                    m_strAsycError = "通道被对方切断";
                    goto ERROR1;
                }

                m_baRecv = ByteArray.Add(m_baRecv, m_baTempRecv, nReaded);
                Debug.Assert(m_baRecv != null, "");

                long remainder = 0;
                bool bRet      = BerNode.IsCompleteBER(m_baRecv,
                                                       0,
                                                       m_baRecv.Length,
                                                       out remainder);
                if (bRet == true)
                {
                    // 发送和接收完成
                    if (SendRecvComplete != null)
                    {
                        SendRecvComplete(this, new EventArgs());
                    }
                    return;
                }


                // 否则继续接收
                try
                {
                    m_baTempRecv = new byte[4096];

                    IAsyncResult result = stream.BeginRead(m_baTempRecv,
                                                           0,
                                                           4096,
                                                           new AsyncCallback(RecvCallback),
                                                           null);
                }
                catch (Exception ex)
                {
                    m_strAsycError = "接收出错: " + ex.Message;

                    goto ERROR1;
                }
            }
            // System.ObjectDisposedException
            catch (Exception ex)
            {
                m_strAsycError = "RecvCallback()出错: " + ExceptionUtil.GetDebugText(ex);

                goto ERROR1;
            }
            return;

ERROR1:
            // 发送和接收完成
            if (SendRecvComplete != null)
            {
                SendRecvComplete(this, new EventArgs());
            }
            return;
        }
예제 #4
0
파일: ZChannel.cs 프로젝트: zszqwe/dp2
        // 接收响应包
        public int SimpleRecvTcpPackage(out byte[] baPackage,
                                        out int nLen,
                                        out string strError)
        {
            strError = "";

            int  nInLen;
            int  wRet        = 0;
            bool bInitialLen = false;

            Debug.Assert(client != null, "client为空");

            baPackage = new byte[4096];
            nInLen    = 0;
            nLen      = 4096; //COMM_BUFF_LEN;

            while (nInLen < nLen)
            {
                if (client == null)
                {
                    strError = "通讯中断";
                    goto ERROR1;
                }

                try
                {
                    wRet = client.GetStream().Read(baPackage,
                                                   nInLen,
                                                   baPackage.Length - nInLen);
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10035)
                    {
                        System.Threading.Thread.Sleep(100);
                        continue;
                    }
                    strError = "recv出错: " + ex.Message;
                    goto ERROR1;
                }
                catch (Exception ex)
                {
                    strError = "recv出错: " + ex.Message;
                    goto ERROR1;
                }

                if (wRet == 0)
                {
                    strError = "Closed by remote peer";
                    goto ERROR1;
                }

                // 得到包的长度

                if ((wRet >= 1 || nInLen >= 1) &&
                    bInitialLen == false)
                {
                    long remainder = 0;
                    bool bRet      = BerNode.IsCompleteBER(baPackage,
                                                           0,
                                                           nInLen + wRet,
                                                           out remainder);
                    if (bRet == true)
                    {
                        nLen = nInLen + wRet;
                        break;
                    }
                }

                nInLen += wRet;
                if (nInLen >= baPackage.Length &&
                    bInitialLen == false)
                {
                    // 扩大缓冲区
                    byte[] temp = new byte[baPackage.Length + 4096];
                    Array.Copy(baPackage, 0, temp, 0, nInLen);
                    baPackage = temp;
                    nLen      = baPackage.Length;
                }
            }

            // 最后规整缓冲区尺寸,如果必要的话
            if (baPackage.Length > nLen)
            {
                byte[] temp = new byte[nLen];
                Array.Copy(baPackage, 0, temp, 0, nLen);
                baPackage = temp;
            }

            return(0);

ERROR1:
            // this.CloseSocket();
            baPackage = null;
            return(-1);
        }
예제 #5
0
        // 接收响应包
        // 注意调用返回后如果发现出错,调主要主动 Close 和重新分配 TcpClient
        // parameters:
        //      nMaxLength  读入等待处理的 bytes 极限数字。超过了这个,还没有找到结束符,就会抛出异常。意在防范攻击。-1 表示不限制
        //      touch_func  回调函数,用于保持通道活跃
        public static async Task <RecvResult> SimpleRecvTcpPackage(TcpClient _client,
                                                                   int nMaxLength,
                                                                   delegate_touch touch_func = null)
        {
            // string strError = "";
            RecvResult result = new RecvResult();

            int  nInLen;
            int  wRet        = 0;
            bool bInitialLen = false;

            Debug.Assert(_client != null, "client为空");

            result.Package = new byte[4096];
            nInLen         = 0;
            result.Length  = 4096; //COMM_BUFF_LEN;

            while (nInLen < result.Length)
            {
                if (_client == null)
                {
                    return(new RecvResult
                    {
                        Value = -1,
                        ErrorInfo = "通讯中断"
                    });
                }

                try
                {
                    wRet = await _client.GetStream().ReadAsync(result.Package,
                                                               nInLen,
                                                               result.Package.Length - nInLen).ConfigureAwait(false);

                    touch_func?.Invoke();
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10035)
                    {
                        System.Threading.Thread.Sleep(100);
                        continue;
                    }
                    return(new RecvResult
                    {
                        Value = -1,
                        ErrorInfo = "recv出错1: " + ex.Message,
                        // "ConnectionAborted"
                        ErrorCode = ((SocketException)ex).SocketErrorCode.ToString()
                    });
                }
                catch (Exception ex)
                {
                    result.Exception = ex;
                    if (ex is IOException && ex.InnerException is SocketException)
                    {
                        // "ConnectionAborted"
                        result.ErrorCode = ((SocketException)ex.InnerException).SocketErrorCode.ToString();
                    }
                    result.ErrorInfo = "recv出错2: " + ex.Message;
                    result.Value     = -1;
                    return(result);
                }

                if (wRet == 0)
                {
                    return(new RecvResult
                    {
                        Value = -1,
                        ErrorCode = "Closed",
                        ErrorInfo = "Closed by remote peer"
                    });
                }

                // 得到包的长度

                if ((wRet >= 1 || nInLen >= 1) &&
                    bInitialLen == false)
                {
                    bool bRet = BerNode.IsCompleteBER(result.Package,
                                                      0,
                                                      nInLen + wRet,
                                                      out long remainder);
                    if (bRet == true)
                    {
                        result.Length = nInLen + wRet;
                        break;
                    }
                }

                nInLen += wRet;
                if (nInLen >= result.Package.Length &&
                    bInitialLen == false)
                {
                    // 扩大缓冲区
                    if (nMaxLength != -1 && result.Package.Length >= nMaxLength)
                    {
                        throw new Exception("接收超过 " + nMaxLength + " bytes 也没有找到通讯包结束符");
                    }

                    byte[] temp = new byte[result.Package.Length + 4096];
                    Array.Copy(result.Package, 0, temp, 0, nInLen);
                    result.Package = temp;
                    result.Length  = result.Package.Length;
                }
            }

            // 最后规整缓冲区尺寸,如果必要的话
            if (result.Package.Length > result.Length)
            {
                byte[] temp = new byte[result.Length];
                Array.Copy(result.Package, 0, temp, 0, result.Length);
                result.Package = temp;
            }

            return(result);

#if NO
ERROR1:
            // this.CloseSocket();
            // baPackage = null;
            return(new RecvResult
            {
                Value = -1,
                ErrorInfo = strError,
                ErrorCode = result.ErrorCode
            });
#endif
        }
예제 #6
0
파일: ZChannel.cs 프로젝트: 919506114/chord
        // 接收响应包
        internal async Task <RecvResult> SimpleRecvTcpPackage()
        {
            string     strError = "";
            RecvResult result   = new RecvResult();

            int  nInLen;
            int  wRet        = 0;
            bool bInitialLen = false;

            Debug.Assert(_client != null, "client为空");

            result.Package = new byte[4096];
            nInLen         = 0;
            result.Length  = 4096; //COMM_BUFF_LEN;

            while (nInLen < result.Length)
            {
                if (_client == null)
                {
                    strError = "通讯中断";
                    goto ERROR1;
                }

                try
                {
                    wRet = await _client.GetStream().ReadAsync(result.Package,
                                                               nInLen,
                                                               result.Package.Length - nInLen);
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10035)
                    {
                        System.Threading.Thread.Sleep(100);
                        continue;
                    }
                    strError = "recv出错: " + ex.Message;
                    goto ERROR1;
                }
                catch (Exception ex)
                {
                    strError = "recv出错: " + ex.Message;
                    goto ERROR1;
                }

                if (wRet == 0)
                {
                    strError = "Closed by remote peer";
                    goto ERROR1;
                }

                // 得到包的长度

                if ((wRet >= 1 || nInLen >= 1) &&
                    bInitialLen == false)
                {
                    bool bRet = BerNode.IsCompleteBER(result.Package,
                                                      0,
                                                      nInLen + wRet,
                                                      out long remainder);
                    if (bRet == true)
                    {
                        result.Length = nInLen + wRet;
                        break;
                    }
                }

                nInLen += wRet;
                if (nInLen >= result.Package.Length &&
                    bInitialLen == false)
                {
                    // 扩大缓冲区
                    byte[] temp = new byte[result.Package.Length + 4096];
                    Array.Copy(result.Package, 0, temp, 0, nInLen);
                    result.Package = temp;
                    result.Length  = result.Package.Length;
                }
            }

            // 最后规整缓冲区尺寸,如果必要的话
            if (result.Package.Length > result.Length)
            {
                byte[] temp = new byte[result.Length];
                Array.Copy(result.Package, 0, temp, 0, result.Length);
                result.Package = temp;
            }

            return(result);

ERROR1:
            // this.CloseSocket();
            // baPackage = null;
            return(new RecvResult {
                Value = -1, ErrorInfo = strError
            });
        }