Example #1
0
        // 处理 Server 端可能发来的 Close
        // return value:
        //      -1  error
        //      0   不是Close
        //      1   是Close,已经迫使ZChannel处于尚未初始化状态
        // return InitialResult:
        //      在 InitialResult::ResultInfo 中返回诊断信息
        async Task <InitialResult> CheckServerCloseRequest()
        {
            if (this._channel.Connected == false || this._channel.DataAvailable == false)
            {
                return(new InitialResult()); // 没有发现问题
            }
            // 注意调用返回后如果发现出错,调主要主动 Close 和重新分配 TcpClient
            RecvResult result = await ZChannel.SimpleRecvTcpPackage(this._channel._client, -1).ConfigureAwait(false);

            if (result.Value == -1)
            {
                this.CloseConnection();
                return(new InitialResult {
                    Value = -1, ErrorInfo = result.ErrorInfo
                });
            }

            BerTree tree1 = new BerTree();

            // TODO: 这里需要捕获异常,然后把 Package Dump 到日志文件(base64 形态),便于事后分析调试
            tree1.m_RootNode.BuildPartTree(result.Package,
                                           0,
                                           result.Package.Length,
                                           out int nTotalLen);

            if (tree1.GetAPDuRoot().m_uTag != BerTree.z3950_close)
            {
                // 不是Close
                return(new InitialResult {
                    Value = 0
                });
            }

            CLOSE_REQUEST closeStruct = new CLOSE_REQUEST();
            int           nRet        = BerTree.GetInfo_closeRequest(
                tree1.GetAPDuRoot(),
                ref closeStruct,
                out string strError);

            if (nRet == -1)
            {
                this.CloseConnection();
                return(new InitialResult {
                    Value = -1, ErrorInfo = strError
                });
            }

            this.CloseConnection();
            return(new InitialResult {
                Value = 1, ResultInfo = closeStruct.m_strDiagnosticInformation
            });
        }
Example #2
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));
 }