示例#1
0
        public void TestMethod3()
        {
            byte[] buffer = Convert.FromBase64String("41YAAAABEKq7zN3u/wARIjNEVWZ3iJkBAAAAJoUGAAAAAgEAAQYAbXlkZWFyAwEAETwAAAADAQD57BfsFwMBAPoeQhM0AwEA/rQBAAADAQDuDOmJFAAAAA==");
            // 分析请求包
            BerTree tree1 = new BerTree();

            tree1.m_RootNode.BuildPartTree(buffer,
                                           0,
                                           buffer.Length,
                                           out int nTotallen);

            BerNode root = tree1.GetAPDuRoot();

            switch (root.m_uTag)
            {
            case BerTree.z3950_initRequest:
                break;

            case BerTree.z3950_searchRequest:
                break;

            case BerTree.z3950_presentRequest:
                break;
            }
        }
示例#2
0
        // 默认的请求处理过程。应可以被重新指定
        // 下级函数,例如处理 Initialize Search Present 的函数,还可以被重新指定
        public async Task <byte[]> DefaultProcessRequest(ZServerChannel channel,
                                                         BerTree request)
        {
            BerNode root = request.GetAPDuRoot();

            switch (root.m_uTag)
            {
            case BerTree.z3950_initRequest:
                if (this.ProcessInitialize == null)
                {
                    return(await DefaultProcessInitialize(channel, request).ConfigureAwait(false));      // 2018/10/10 add configure
                }
                else
                {
                    ProcessInitializeEventArgs e = new ProcessInitializeEventArgs();
                    e.Request = request;
                    this.ProcessInitialize(channel, e);
                    return(e.Response);
                }
                break;

            case BerTree.z3950_searchRequest:
                if (this.ProcessSearch == null)
                {
                    return(await DefaultProcessSearch(channel, request).ConfigureAwait(false));    // 2018/10/10 add configure
                }
                else
                {
                    ProcessSearchEventArgs e = new ProcessSearchEventArgs();
                    e.Request = request;
                    this.ProcessSearch(channel, e);
                    return(e.Response);
                }
                break;

            case BerTree.z3950_presentRequest:
                if (this.ProcessPresent == null)
                {
                    return(await DefaultProcessPresent(channel, request).ConfigureAwait(false));    // 2018/10/10 add configure
                }
                else
                {
                    ProcessPresentEventArgs e = new ProcessPresentEventArgs();
                    e.Request = request;
                    this.ProcessPresent(channel, e);
                    return(e.Response);
                }
                break;
            }

            return(new byte[0]);
            // TODO 如果将来嫌日志中记载 BerNode Dump 结果体积太大,Dump 结果可以考虑不进入日志
            //string text = JsonConvert.SerializeObject(root, Formatting.Indented);
            //throw new UnknownApduException(string.Format("无法识别的 APDU tag[{0}]\r\nBerNode={1}", root.m_uTag, text));
        }
示例#3
0
        public async Task <byte[]> DefaultProcessPresent(ZServerChannel channel,
                                                         BerTree request)
        {
            BerNode root = request.GetAPDuRoot();

            // 解码Search请求包
            int nRet = ZProcessor.Decode_PresentRequest(
                root,
                out PresentRequestInfo info,
                out string strError);

            if (nRet == -1)
            {
                goto ERROR1;
            }

            if (channel.EnsureProperty()._bInitialized == false)
            {
                return(null);
            }

            PresentGetRecordsEventArgs e = new PresentGetRecordsEventArgs();

            if (this.PresentGetRecords == null)
            {
                // 模拟返回一条记录
                e.Records = new List <RetrivalRecord>();
                RetrivalRecord record = new RetrivalRecord();
                // TODO: 准备数据
                e.Records.Add(record);
            }
            else
            {
                e.Request = info;
                this.PresentGetRecords(channel, e);
            }

            // 编码Present响应包
            nRet = ZProcessor.Encode_PresentResponse(info,
                                                     e.Records,
                                                     e.Diag,
                                                     e.TotalCount,
                                                     out byte[] baResponsePackage);
            if (nRet == -1)
            {
                goto ERROR1;
            }

            return(baResponsePackage);

ERROR1:
            // TODO: 将错误原因写入日志
            return(null);
        }
示例#4
0
        public void TestMethod1()
        {
            BerTree tree = new BerTree();
            BerNode root = null;

            root = tree.m_RootNode.NewChildConstructedNode(
                BerTree.z3950_presentResponse,
                BerNode.ASN1_CONTEXT);
            byte[] baPackage = null;
            root.EncodeBERPackage(ref baPackage);
        }
示例#5
0
        public async Task <byte[]> DefaultProcessSearch(ZServerChannel channel,
                                                        BerTree request)
        {
            BerNode root = request.GetAPDuRoot();

            // 解码Search请求包
            int nRet = ZProcessor.Decode_SearchRequest(
                root,
                out SearchRequestInfo info,
                out string strError);

            if (nRet == -1)
            {
                goto ERROR1;
            }

            if (channel.EnsureProperty()._bInitialized == false)
            {
                return(null);
            }

            SearchSearchEventArgs e = new SearchSearchEventArgs();

            e.Request = info;
            if (this.SearchSearch == null)
            {
                // 返回模拟的结果,假装命中了一条记录
                e.Result = new ZClient.SearchResult {
                    Value = 1
                };
            }
            else
            {
                this.SearchSearch(channel, e);
            }

            // 编码Search响应包
            nRet = ZProcessor.Encode_SearchResponse(info,
                                                    e.Result,
                                                    e.Diag,
                                                    out byte[] baResponsePackage,
                                                    out strError);
            if (nRet == -1)
            {
                goto ERROR1;
            }

            return(baResponsePackage);

ERROR1:
            // TODO: 将错误原因写入日志
            return(null);
        }
示例#6
0
文件: ZClient.cs 项目: keji56/chord
        // 处理 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
            });
        }
示例#7
0
        // 默认的请求处理过程。应可以被重新指定
        // 下级函数,例如处理 Initialize Search Present 的函数,还可以被重新指定
        public async Task <byte[]> DefaultProcessRequest(ZServerChannel channel,
                                                         BerTree request)
        {
            BerNode root = request.GetAPDuRoot();

            switch (root.m_uTag)
            {
            case BerTree.z3950_initRequest:
                if (this.ProcessInitialize == null)
                {
                    return(await DefaultProcessInitialize(channel, request));
                }
                else
                {
                    ProcessInitializeEventArgs e = new ProcessInitializeEventArgs();
                    e.Request = request;
                    this.ProcessInitialize(channel, e);
                    return(e.Response);
                }
                break;

            case BerTree.z3950_searchRequest:
                if (this.ProcessSearch == null)
                {
                    return(await DefaultProcessSearch(channel, request));
                }
                else
                {
                    ProcessSearchEventArgs e = new ProcessSearchEventArgs();
                    e.Request = request;
                    this.ProcessSearch(channel, e);
                    return(e.Response);
                }
                break;

            case BerTree.z3950_presentRequest:
                if (this.ProcessPresent == null)
                {
                    return(await DefaultProcessPresent(channel, request));
                }
                else
                {
                    ProcessPresentEventArgs e = new ProcessPresentEventArgs();
                    e.Request = request;
                    this.ProcessPresent(channel, e);
                    return(e.Response);
                }
                break;
            }
            return(new byte[0]);
        }
示例#8
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()); // 没有发现问题
            }
            RecvResult result = await this._channel.SimpleRecvTcpPackage();

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

            BerTree tree1 = new BerTree();

            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)
            {
                return new InitialResult {
                           Value = -1, ErrorInfo = strError
                }
            }
            ;

            this.CloseConnection();
            return(new InitialResult {
                Value = 1, ResultInfo = closeStruct.m_strDiagnosticInformation
            });
        }
示例#9
0
        public static string BuildInitialResultInfo(INIT_RESPONSE info)
        {
            string strText = "";

            strText += "reference-id:\t" + info.m_strReferenceId + "\r\n";
            strText += "options:\t" + info.m_strOptions + "\r\n";
            strText += "preferred-message-size:\t" + info.m_lPreferredMessageSize.ToString() + "\r\n";
            strText += "exceptional-record-size:\t" + info.m_lExceptionalRecordSize.ToString() + "\r\n";

            strText += "\r\n--- Result Code ---\r\n";
            strText += "initial-result:\t" + info.m_nResult.ToString() + "\r\n";

            strText += "\r\n--- Implementation information ---\r\n";
            strText += "implementation-id:\t" + info.m_strImplementationId + "\r\n";
            strText += "implementation-name:\t" + info.m_strImplementationName + "\r\n";
            strText += "implementation-version:\t" + info.m_strImplementationVersion + "\r\n";

            strText += "\r\n--- Error Code and Message ---\r\n";
            strText += "error-code:\t" + info.m_lErrorCode.ToString() + "\r\n";
            strText += "error-messsage:\t" + info.m_strErrorMessage + "\r\n";

            if (info.m_charNego != null)
            {
                strText += "\r\n--- Charset Negotiation Parameters ---\r\n";

                if (BerTree.GetBit(info.m_strOptions, 17) == false)
                {
                    strText += "options bit 17 is false, not allow negotiation\r\n";
                }

                strText += "charnego-encoding-level-oid:\t" + info.m_charNego.EncodingLevelOID + "(note: UTF-8 is: " + CharsetNeogatiation.Utf8OID + ")\r\n";

                strText += "charnego-records-in-selected-charsets:\t" + info.m_charNego.RecordsInSelectedCharsets.ToString() + "\r\n";
            }

            return(strText);
        }
示例#10
0
        // 处理一个通道的通讯活动
        public async override void HandleClient(TcpClient tcpClient,
                                                Action close_action,
                                                CancellationToken token)
        {
            List <byte> cache = new List <byte>();

            ZServerChannel channel = _tcpChannels.Add(tcpClient, () => { return(new ZServerChannel()); }) as ZServerChannel;

            // 允许对 channel 做额外的初始化
            if (this.ChannelOpened != null)
            {
                this.ChannelOpened(channel, new EventArgs());
            }
            try
            {
                string ip = "";

                try
                {
                    ip = GetClientIP(tcpClient);
                    channel.Touch();

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }
                        // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                        BerTree request = await ZProcessor.GetIncomingRequest(
                            cache,
                            tcpClient,
                            () => channel.Touch()).ConfigureAwait(false);  // 2018/10/10 add configure

                        if (request == null)
                        {
                            Console.WriteLine("client close on request " + i);
                            break;
                        }
                        Console.WriteLine("request " + i);

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        byte[] response = null;
                        if (this.ProcessRequest == null)
                        {
                            response = await DefaultProcessRequest(channel, request).ConfigureAwait(false);  // 2018/10/10 add configure
                        }
                        else
                        {
                            ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                            e.Request = request;
                            this.ProcessRequest(channel, e);
                            response = e.Response;
                        }

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                        Result result = await ZProcessor.SendResponse(response, tcpClient).ConfigureAwait(false); // 2018/10/10 add configure

                        channel.Touch();
                        if (result.Value == -1)
                        {
                            Console.WriteLine("error on response " + i + ": " + result.ErrorInfo);
                            break;
                        }

                        i++;
                    }
                }
                catch (Exception ex)
                {
                    if (ex.InnerException != null && ex.InnerException is ObjectDisposedException)
                    {
                        // 这种情况一般是 server 主动清理闲置通道导致的,不记入日志
                    }
                    else if (ex is ObjectDisposedException)
                    {
                        // 这种情况一般是 client close 通道导致,不记入日志
                    }
                    else
                    {
                        string strName = "ip:" + ip
                                         + channel == null ? "(null)" : " channel:" + channel.GetHashCode();
                        string strError = strName + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex);
                        LibraryManager.Log?.Error(strError);
                        // Console.WriteLine(strError);
                    }
                }
                finally
                {
#if NO
                    outputStream.Flush();
                    outputStream.Close();
                    outputStream = null;

                    inputStream.Close();
                    inputStream = null;
#endif

                    // tcpClient.Close();

                    // 清除全局结果集
                }
            }
            finally
            {
                _tcpChannels.Remove(channel);
#if NO
                if (this.ChannelClosed != null)
                {
                    ChannelClosedEventArgs e = new ChannelClosedEventArgs();
                    e.Channel = channel;
                    this.ChannelClosed(channel, e);
                }
#endif
                channel.Close();
                if (close_action != null)
                {
                    close_action.Invoke();
                }
            }
        }
示例#11
0
        // return:
        //		-1	error
        //		0	fail
        //		1	succeed
        int DoSearch(
            ZConnection connection,
            string strQuery,
            Encoding queryTermEncoding,
            string[] dbnames,
            string strResultSetName,
            out int nResultCount,
            out string strError)
        {
            strError = "";

            BerTree tree = new BerTree();
            SEARCH_REQUEST struSearch_request = new SEARCH_REQUEST();
            byte[] baPackage = null;
            int nRet;
            int nRecvLen;
            //int nMax;
            //int i;



            // -->
            BerTree tree1 = new BerTree();
            int nTotlen = 0;


            nResultCount = 0;

            struSearch_request.m_dbnames = dbnames;

            Debug.Assert(struSearch_request.m_dbnames.Length != 0, "");

            struSearch_request.m_strReferenceId = this.CurrentRefID;
            struSearch_request.m_lSmallSetUpperBound = 0;
            struSearch_request.m_lLargeSetLowerBound = 1;
            struSearch_request.m_lMediumSetPresentNumber = 0;
            struSearch_request.m_nReplaceIndicator = 1;
            struSearch_request.m_strResultSetName = strResultSetName;   // "default";
            struSearch_request.m_strSmallSetElementSetNames = "";
            struSearch_request.m_strMediumSetElementSetNames = "";
            struSearch_request.m_strPreferredRecordSyntax = ZTargetControl.GetLeftValue(this.comboBox_recordSyntax.Text);    //  this.CurrentTargetInfo.PreferredRecordSyntax;   // BerTree.MARC_SYNTAX;
            struSearch_request.m_strQuery = strQuery;
            struSearch_request.m_nQuery_type = 1;
            struSearch_request.m_queryTermEncoding = queryTermEncoding;
           

            // m_search_response.m_lErrorCode = 0;

            nRet = tree.SearchRequest(struSearch_request,
                out baPackage);

            if (nRet == -1)
            {
                strError = "CBERTree::SearchRequest() fail!";
                return -1;
            }
#if NOTCPIP
	if (m_hSocket == INVALID_SOCKET) {
		strError = "socket已经关闭!";
		return -1;
	}
#endif


            #if DUMPTOFILE
            string strBinFile = this.MainForm.DataDir + "\\searchrequest.bin";
            File.Delete(strBinFile);
            DumpPackage(strBinFile,
                baPackage);
            string strLogFile = this.MainForm.DataDir + "\\searchrequest.txt";
            File.Delete(strLogFile);
            tree.m_RootNode.DumpToFile(strLogFile);
            #endif



            nRet = CheckConnect(
                connection,
                out strError);
            if (nRet == -1)
                return -1;

            /*
            nRet = this.ZChannel.SendTcpPackage(
                baPackage,
                baPackage.Length,
                out strError);
            if (nRet == -1 || nRet == 1)
            {
                // CloseZAssociation();
                return -1;
            }
            //AfxMessageBox("发送成功");


            baPackage = null;
            nRet = this.ZChannel.RecvTcpPackage(
                        out baPackage,
                        out nRecvLen,
                        out strError);
            if (nRet == -1)
            {
                // CloseZAssociation();
                return -1;
            }
             * */

            byte [] baOutPackage = null;
            nRet = connection.ZChannel.SendAndRecv(
                baPackage,
                out baOutPackage,
                out nRecvLen,
                out strError);
            if (nRet == -1)
                return -1;

#if DEBUG
            if (nRet == 0)
            {
                Debug.Assert(strError == "", "");
            }
#endif

#if DUPMTOFILE
	DeleteFile("searchresponse.bin");
	DumpPackage("searchresponse.bin",
				(char *)baOutPackage.GetData(),
				baOutPackage.GetSize());
#endif

            tree1.m_RootNode.BuildPartTree(baOutPackage,
                0,
                baOutPackage.Length,
                out nTotlen);

            SEARCH_RESPONSE search_response = new SEARCH_RESPONSE();
            nRet = BerTree.GetInfo_SearchResponse(tree1.GetAPDuRoot(),
                                   ref search_response,
                                   true,
                                   out strError);
            if (nRet == -1)
                return -1;

#if DUMPTOFILE
	DeleteFile("SearchResponse.txt"); 
	tree1.m_RootNode.DumpDebugInfoToFile("SearchResponse.txt");
#endif
            /*
	nRet = FitDebugInfo_SearchResponse(&tree1,
							  strError);
	if (nRet == -1) {
		AfxMessageBox(strError);
		return;
	}
	*/
            nResultCount = (int)search_response.m_lResultCount;

            if (search_response.m_nSearchStatus != 0)	// 不一定是1
                return 1;

            strError = "Search Fail: diagRecords:\r\n" + search_response.m_diagRecords.GetMessage();
            return 0;	// search fail
        }
示例#12
0
        // 获得记录
        // 不确保一定可以获得nCount个
        // parameters:
        //		nStart	开始记录(从0计算)
        int DoOncePresent(
            ZConnection connection,
            string strResultSetName,
            int nStart,
            int nCount,
            string strElementSetName,
            string strPreferredRecordSyntax,
            out RecordCollection records,
            out string strError)
        {
            records = null;
            strError = "";

            if (nCount == 0)
            {
                strError = "nCount为0";
                return 0;
            }


            BerTree tree = new BerTree();
            PRESENT_REQUEST struPresent_request = new PRESENT_REQUEST();
            byte[] baPackage = null;
            int nRet;
            int nRecvLen;

            // -->
            BerTree tree1 = new BerTree();
            int nTotlen = 0;

            struPresent_request.m_strReferenceId = this.CurrentRefID;
            struPresent_request.m_strResultSetName = strResultSetName; // "default";
            struPresent_request.m_lResultSetStartPoint = nStart + 1;
            struPresent_request.m_lNumberOfRecordsRequested = nCount;
            struPresent_request.m_strElementSetNames = strElementSetName;
            struPresent_request.m_strPreferredRecordSyntax = strPreferredRecordSyntax;

            nRet = tree.PresentRequest(struPresent_request,
                                     out baPackage);
            if (nRet == -1)
            {
                strError = "CBERTree::PresentRequest() fail!";
                return -1;
            }


#if DUMPTOFILE
	DeleteFile("presentrequest.bin");
	DumpPackage("presentrequest.bin",
		(char *)baPackage.GetData(),
		baPackage.GetSize());
	DeleteFile ("presentrequest.txt");
	tree.m_RootNode.DumpToFile("presentrequest.txt");
#endif

            nRet = CheckConnect(
                connection,
                out strError);
            if (nRet == -1)
                return -1;

            /*
            nRet = this.ZChannel.SendTcpPackage(
                baPackage,
                baPackage.Length,
                out strError);
            if (nRet == -1 || nRet == 1)
            {
                // CloseZAssociation();
                return -1;
            }

            //////////////


            baPackage = null;
            nRet = this.ZChannel.RecvTcpPackage(
                        out baPackage,
                        out nRecvLen,
                        out strError);
            if (nRet == -1)
            {
                // CloseZAssociation();
                goto ERROR1;
            }
             * */

            byte [] baOutPackage = null;
            nRet = connection.ZChannel.SendAndRecv(
                baPackage,
                out baOutPackage,
                out nRecvLen,
                out strError);
            if (nRet == -1)
                return -1;

#if DUMPTOFILE	
	DeleteFile("presendresponse.bin");
	DumpPackage("presentresponse.bin",
				(char *)baPackage.GetData(),
				baPackage.GetSize());
#endif


            tree1.m_RootNode.BuildPartTree(baOutPackage,
                0,
                baOutPackage.Length,
                out nTotlen);

#if DUMPTOFILE
	DeleteFile("PresentResponse.txt"); 
	tree1.m_RootNode.DumpDebugInfoToFile("PresentResponse.txt");
#endif

            SEARCH_RESPONSE search_response = new SEARCH_RESPONSE();
            nRet = BerTree.GetInfo_PresentResponse(tree1.GetAPDuRoot(),
                                   ref search_response,
                                   out records,
                                   true,
                                   out strError);
            if (nRet == -1)
                goto ERROR1;

            /*
            nRet = FitDebugInfo_PresentResponse(&tree1,
                                      strError);
            if (nRet == -1) {
                goto ERROR1;
            }

            DeleteFile("PresentResponse.txt"); 
            tree1.m_RootNode.DumpDebugInfoToFile("PresentResponse.txt");
            */


            if (search_response.m_diagRecords.Count != 0)
            {
                /*
                string strDiagText;
                string strAddInfo;

                nRet = GetDiagTextByNumber("bib1diag.txt",
                                m_search_response.m_nDiagCondition,
                                strDiagText,
                                strAddInfo,
                                strError);
                if (nRet == -1) {
                    if (this->m_bAllowMessageBox)
                        AfxMessageBox(strError);
                    return -1;
                }
                if (strDiagText.GetLength())
                    strError = strDiagText;
                else
                    strError.Format("diag condition[%d] diag set id[%s]",
                    m_search_response.m_nDiagCondition,
                    m_search_response.m_strDiagSetID);
                 * */
                strError = "error diagRecords:\r\n\r\n---\r\n" + search_response.m_diagRecords.GetMessage();
                return -1;
            }

            return 0;
        ERROR1:
            return -1;
        }
示例#13
0
        public /*async*/ Task <byte[]> DefaultProcessInitialize(ZServerChannel channel,
                                                                BerTree request)
        {
            BerNode root = request.GetAPDuRoot();

            Encoding encoding = Encoding.GetEncoding(936);

REDO:
            int nRet = ZProcessor.Decode_InitRequest(
                root,
                encoding,
                out InitRequestInfo info,
                out string strDebugInfo,
                out string strError);

            if (nRet == -1)
            {
                goto ERROR1;
            }

            // 可以用groupid来表示字符集信息

            InitResponseInfo response_info = new InitResponseInfo();

            if (info.m_charNego != null)
            {
                /* option
                 *
                 * search                 (0),
                 * present                (1),
                 * delSet                 (2),
                 * resourceReport         (3),
                 * triggerResourceCtrl    (4),
                 * resourceCtrl           (5),
                 * accessCtrl             (6),
                 * scan                   (7),
                 * sort                   (8),
                 * --                     (9) (reserved)
                 * extendedServices       (10),
                 * level-1Segmentation    (11),
                 * level-2Segmentation    (12),
                 * concurrentOperations   (13),
                 * namedResultSets        (14)
                 * 15 Encapsulation  Z39.50-1995 Amendment 3: Z39.50 Encapsulation
                 * 16 resultCount parameter in Sort Response  See Note 8 Z39.50-1995 Amendment 1: Add resultCount parameter to Sort Response
                 * 17 Negotiation Model  See Note 9 Model for Z39.50 Negotiation During Initialization
                 * 18 Duplicate Detection See Note 1  Z39.50 Duplicate Detection Service
                 * 19 Query type 104
                 * }
                 */
                response_info.m_strOptions = "yynnnnnnnnnnnnn";

                if (info.m_charNego.EncodingLevelOID == CharsetNeogatiation.Utf8OID)
                {
                    BerTree.SetBit(ref response_info.m_strOptions,
                                   17,
                                   true);
                    response_info.m_charNego = info.m_charNego;

                    // 2018/9/19
                    // 如果最初解码用的编码方式不是 UTF8,则需要重新解码
                    if (encoding != Encoding.UTF8)
                    {
                        encoding = Encoding.UTF8;
                        goto REDO;
                    }
                    channel.EnsureProperty()._searchTermEncoding = Encoding.UTF8;
                    if (info.m_charNego.RecordsInSelectedCharsets != -1)
                    {
                        response_info.m_charNego.RecordsInSelectedCharsets = info.m_charNego.RecordsInSelectedCharsets; // 依从前端的请求
                        if (response_info.m_charNego.RecordsInSelectedCharsets == 1)
                        {
                            channel.EnsureProperty()._marcRecordEncoding = Encoding.UTF8;
                        }
                    }
                }
            }
            else
            {
                response_info.m_strOptions = "yynnnnnnnnnnnnn";
            }



            // 判断info中的信息,决定是否接受Init请求。

            // ZServerChannel 初始化设置一些信息。这样它一直携带着伴随生命周期全程
            Result result = AutoSetChannelProperty(channel, info);

            if (result.Value == -1)
            {
                response_info.m_nResult = 0;
                channel.EnsureProperty()._bInitialized = false;

                ZProcessor.SetInitResponseUserInfo(response_info,
                                                   "1.2.840.10003.4.1",                                                              // string strOID,
                                                   string.IsNullOrEmpty(result.ErrorCode) ? 100 : Convert.ToInt32(result.ErrorCode), // (unspecified) error
                                                   result.ErrorInfo);
                goto DO_RESPONSE;
            }

#if NO
            if (String.IsNullOrEmpty(info.m_strID) == true)
            {
                ZConfig config = AutoGetZConfig(channel, info, out strError);
                if (config == null)
                {
                    ZProcessor.SetInitResponseUserInfo(response_info,
                                                       "", // string strOID,
                                                       0,  // long lErrorCode,
                                                       strError);
                    goto DO_RESPONSE;
                }
                // 如果定义了允许匿名登录
                if (String.IsNullOrEmpty(config.AnonymousUserName) == false)
                {
                    info.m_strID       = config.AnonymousUserName;
                    info.m_strPassword = config.AnonymousPassword;
                }
                else
                {
                    response_info.m_nResult = 0;
                    channel.SetProperty()._bInitialized = false;

                    ZProcessor.SetInitResponseUserInfo(response_info,
                                                       "", // string strOID,
                                                       0,  // long lErrorCode,
                                                       "不允许匿名登录");
                    goto DO_RESPONSE;
                }
            }
#endif

            if (this.InitializeLogin != null)
            {
                InitializeLoginEventArgs e = new InitializeLoginEventArgs();

                this.InitializeLogin(channel, e);
                if (e.Result.Value == -1 || e.Result.Value == 0)
                {
                    response_info.m_nResult = 0;
                    channel.EnsureProperty()._bInitialized = false;

                    ZProcessor.SetInitResponseUserInfo(response_info,
                                                       "1.2.840.10003.4.1",                                                                  // string strOID,
                                                       string.IsNullOrEmpty(e.Result.ErrorCode) ? 101 : Convert.ToInt32(e.Result.ErrorCode), // Access-control failure
                                                       e.Result.ErrorInfo);
                }
                else
                {
                    response_info.m_nResult = 1;
                    channel.EnsureProperty()._bInitialized = true;
                }
            }
            else
            {
                response_info.m_nResult = 1;
                channel.EnsureProperty()._bInitialized = true;
            }

#if NO
            // 进行登录
            // return:
            //      -1  error
            //      0   登录未成功
            //      1   登录成功
            nRet = DoLogin(info.m_strGroupID,
                           info.m_strID,
                           info.m_strPassword,
                           out strError);
            if (nRet == -1 || nRet == 0)
            {
                response_info.m_nResult = 0;
                this._bInitialized      = false;

                ZProcessor.SetInitResponseUserInfo(response_info,
                                                   "", // string strOID,
                                                   0,  // long lErrorCode,
                                                   strError);
            }
            else
            {
                response_info.m_nResult = 1;
                channel._bInitialized   = true;
            }
#endif

DO_RESPONSE:
            // 填充 response_info 的其它结构
            response_info.m_strReferenceId = info.m_strReferenceId;

            //if (channel._property == null)
            //    channel._property = new ChannelPropterty();

            if (info.m_lPreferredMessageSize != 0)
            {
                channel.EnsureProperty().PreferredMessageSize = info.m_lPreferredMessageSize;
            }
            // 极限
            if (channel.EnsureProperty().PreferredMessageSize > ZServerChannelProperty.MaxPreferredMessageSize)
            {
                channel.EnsureProperty().PreferredMessageSize = ZServerChannelProperty.MaxPreferredMessageSize;
            }
            response_info.m_lPreferredMessageSize = channel.EnsureProperty().PreferredMessageSize;

            if (info.m_lExceptionalRecordSize != 0)
            {
                channel.EnsureProperty().ExceptionalRecordSize = info.m_lExceptionalRecordSize;
            }
            // 极限
            if (channel.EnsureProperty().ExceptionalRecordSize > ZServerChannelProperty.MaxExceptionalRecordSize)
            {
                channel.EnsureProperty().ExceptionalRecordSize = ZServerChannelProperty.MaxExceptionalRecordSize;
            }
            response_info.m_lExceptionalRecordSize = channel.EnsureProperty().ExceptionalRecordSize;

            response_info.m_strImplementationId      = "Digital Platform";
            response_info.m_strImplementationName    = "dp2Capo";
            response_info.m_strImplementationVersion = "1.0";

            // BerTree tree = new BerTree();
            ZProcessor.Encode_InitialResponse(response_info,
                                              out byte[] baResponsePackage);

            return(Task.FromResult(baResponsePackage));

ERROR1:
            // TODO: 将错误原因写入日志
            LibraryManager.Log?.Error(strError);
            return(null);
        }
示例#14
0
文件: Session.cs 项目: renyh1013/dp2
        /// <summary>
        /// Session处理轮回
        /// </summary>
        public void Processing()
        {
            int nRet = 0;
            string strError = "";

            try
            {
                byte[] baPackage = null;
                int nLen = 0;
                byte[] baResponsePackage = null;

                for (; ; )
                {
                    _activateTime = DateTime.Now;
                    // 接收前端请求
                    nRet = RecvTcpPackage(out baPackage,
                        out nLen,
                        out strError);
                    if (nRet == -1)
                        goto ERROR_NOT_LOG;

                    // 分析请求包
                    BerTree tree1 = new BerTree();
                    int nTotlen = 0;

                    tree1.m_RootNode.BuildPartTree(baPackage,
                        0,
                        baPackage.Length,
                        out nTotlen);

                    BerNode root = tree1.GetAPDuRoot();

                    switch (root.m_uTag)
                    {
                        case BerTree.z3950_initRequest:
                            {
                                InitRequestInfo info = null;
                                string strDebugInfo = "";
                                nRet = Decode_InitRequest(
                                    root,
                                    out info,
                                    out strDebugInfo,
                                    out strError);
                                if (nRet == -1)
                                    goto ERROR1;

                                // 可以用groupid来表示字符集信息

                                InitResponseInfo response_info = new InitResponseInfo();

                                // 判断info中的信息,决定是否接受Init请求。

                                if (String.IsNullOrEmpty(info.m_strID) == true)
                                {
                                    // 如果定义了允许匿名登录
                                    if (String.IsNullOrEmpty(this._service.AnonymousUserName) == false)
                                    {
                                        info.m_strID = this._service.AnonymousUserName;
                                        info.m_strPassword = this._service.AnonymousPassword;
                                    }
                                    else
                                    {
                                        response_info.m_nResult = 0;
                                        this._bInitialized = false;

                                        SetInitResponseUserInfo(response_info,
                                            "", // string strOID,
                                            0,  // long lErrorCode,
                                            "不允许匿名登录");
                                        goto DO_RESPONSE;
                                    }
                                }

                                // 进行登录
                                // return:
                                //      -1  error
                                //      0   登录未成功
                                //      1   登录成功
                                nRet = DoLogin(info.m_strGroupID,
                                    info.m_strID,
                                    info.m_strPassword,
                                    out strError);
                                if (nRet == -1 || nRet == 0)
                                {
                                    response_info.m_nResult = 0;
                                    this._bInitialized = false;

                                    SetInitResponseUserInfo(response_info,
                                        "", // string strOID,
                                        0,  // long lErrorCode,
                                        strError);
                                }
                                else
                                {
                                    response_info.m_nResult = 1;
                                    this._bInitialized = true;
                                }

                            DO_RESPONSE:
                                // 填充response_info的其它结构
                                response_info.m_strReferenceId = info.m_strReferenceId;  // .m_strID; BUG!!! 2007/11/2

                                if (info.m_lPreferredMessageSize != 0)
                                    this._lPreferredMessageSize = info.m_lPreferredMessageSize;
                                // 极限
                                if (this._lPreferredMessageSize > MaxPreferredMessageSize)
                                    this._lPreferredMessageSize = MaxPreferredMessageSize;
                                response_info.m_lPreferredMessageSize = this._lPreferredMessageSize;

                                if (info.m_lExceptionalRecordSize != 0)
                                    this._lExceptionalRecordSize = info.m_lExceptionalRecordSize;
                                // 极限
                                if (this._lExceptionalRecordSize > MaxExceptionalRecordSize)
                                    this._lExceptionalRecordSize = MaxExceptionalRecordSize;
                                response_info.m_lExceptionalRecordSize = this._lExceptionalRecordSize;

                                response_info.m_strImplementationId = "Digital Platform";
                                response_info.m_strImplementationName = "dp2ZServer";
                                response_info.m_strImplementationVersion = "1.0";

                                if (info.m_charNego != null)
                                {
                                    /* option
* 
search                 (0), 
present                (1), 
delSet                 (2),
resourceReport         (3),
triggerResourceCtrl    (4),
resourceCtrl           (5), 
accessCtrl             (6),
scan                   (7),
sort                   (8), 
--                     (9) (reserved)
extendedServices       (10),
level-1Segmentation    (11),
level-2Segmentation    (12),
concurrentOperations   (13),
namedResultSets        (14)
15 Encapsulation  Z39.50-1995 Amendment 3: Z39.50 Encapsulation 
16 resultCount parameter in Sort Response  See Note 8 Z39.50-1995 Amendment 1: Add resultCount parameter to Sort Response  
17 Negotiation Model  See Note 9 Model for Z39.50 Negotiation During Initialization  
18 Duplicate Detection See Note 1  Z39.50 Duplicate Detection Service  
19 Query type 104 
* }
*/
                                    response_info.m_strOptions = "yynnnnnnnnnnnnn";

                                    if (info.m_charNego.EncodingLevelOID == CharsetNeogatiation.Utf8OID)
                                    {
                                        BerTree.SetBit(ref response_info.m_strOptions,
                                            17,
                                            true);
                                        response_info.m_charNego = info.m_charNego;
                                        this._searchTermEncoding = Encoding.UTF8;
                                        if (info.m_charNego.RecordsInSelectedCharsets != -1)
                                        {
                                            response_info.m_charNego.RecordsInSelectedCharsets = info.m_charNego.RecordsInSelectedCharsets; // 依从前端的请求
                                            if (response_info.m_charNego.RecordsInSelectedCharsets == 1)
                                                this._marcRecordEncoding = Encoding.UTF8;
                                        }
                                    }
                                }
                                else
                                {
                                    response_info.m_strOptions = "yynnnnnnnnnnnnn";
                                }



                                BerTree tree = new BerTree();
                                nRet = Encode_InitialResponse(response_info,
                                    out baResponsePackage);
                                if (nRet == -1)
                                    goto ERROR1;


                            }
                            break;
                        case BerTree.z3950_searchRequest:
                            {
                                SearchRequestInfo info = null;
                                // 解码Search请求包
                                nRet = Decode_SearchRequest(
                                    root,
                                    out info,
                                    out strError);
                                if (nRet == -1)
                                    goto ERROR1;

                                if (_bInitialized == false)
                                    goto ERROR_NOT_LOG;


                                // 编码Search响应包
                                nRet = Encode_SearchResponse(info,
                                    out baResponsePackage,
                                    out strError);
                                if (nRet == -1)
                                    goto ERROR1;

                            }
                            break;

                        case BerTree.z3950_presentRequest:
                            {
                                PresentRequestInfo info = null;
                                // 解码Search请求包
                                nRet = Decode_PresentRequest(
                                    root,
                                    out info,
                                    out strError);
                                if (nRet == -1)
                                    goto ERROR1;

                                if (_bInitialized == false)
                                    goto ERROR_NOT_LOG;

                                // 编码Present响应包
                                nRet = Encode_PresentResponse(info,
                                    out baResponsePackage);
                                if (nRet == -1)
                                    goto ERROR1;

                            }
                            break;
                        default:
                            break;
                    }


                    // 发出响应包
                    // return:
                    //      -1  出错
                    //      0   正确发出
                    //      1   发出前,发现流中有未读入的数据
                    nRet = SendTcpPackage(baResponsePackage,
                        baResponsePackage.Length,
                        out strError);
                    if (nRet == -1)
                        goto ERROR_NOT_LOG;
                }

            }
            catch (ThreadInterruptedException)
            {
                // string dummy = e.Message;     // Needed for to remove compile warning
            }
            catch (Exception x)
            {
                /*
				if(m_clientSocket.Connected)
				{
					// SendData("421 Service not available, closing transmission channel\r\n");

					// m_pSMTP_Server.WriteErrorLog(x.Message);
				}
				else
				{

				}
                 * */
                strError = "Session Processing()俘获异常: " + ExceptionUtil.GetDebugText(x);
                goto ERROR1;
            }
            finally
            {
                _service.RemoveSession(this.SessionID);
                this.CloseSocket();
            }
            return;
        ERROR1:
            // 将strError写入日志
            this._service.Log.WriteEntry(strError, EventLogEntryType.Error);
            return;
        ERROR_NOT_LOG:
            // 不写入日志
            return;
        }
示例#15
0
        async Task <Result> ProcessAndResponse(
            TcpClient tcpClient,
            Action close_action,
            ZServerChannel channel,
            BerTree request,
            CancellationToken token)
        {
            string name  = "";
            string ip    = "";
            bool   error = false;

            try
            {
                name = channel.GetDebugName(tcpClient);
                ip   = TcpServer.GetClientIP(tcpClient);

                byte[] response = null;
                if (this.ProcessRequest == null)
                {
                    response = await DefaultProcessRequest(channel, request).ConfigureAwait(false);  // 2018/10/10 add configure
                }
                else
                {
                    ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                    e.Request = request;
                    this.ProcessRequest(channel, e);
                    response = e.Response;
                }

                channel.Touch();
                if (token != null && token.IsCancellationRequested)
                {
                    error = true;
                    return(new Result {
                        Value = -1, ErrorInfo = "Cancelled"
                    });
                }

                // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                Result result = await ZProcessor.SendResponse(response, tcpClient).ConfigureAwait(false); // 2018/10/10 add configure

                channel.Touch();
                if (result.Value == -1)
                {
                    Console.WriteLine("error on response " + name + ": " + result.ErrorInfo);
                    error = true;
                    return(result);
                }

                return(new Result());
            }
            catch (Exception ex)
            {
                if (ex is UnknownApduException ||
                    ex is BadApduException)
                {
                    IpTable.SetInBlackList(ip, TimeSpan.FromHours(1));
                    LibraryManager.Log?.Info(string.Format("IP 地址 {0} 已被加入黑名单,时限一个小时", ip));
                }

                if (channel != null)
                {
                    channel.Close();
                    if (close_action != null)
                    {
                        close_action.Invoke();
                    }
                    LogException(ex, channel, name);
                    channel = null;
                }
                else
                {
                    LogException(ex, channel, name);
                }

                return(new Result {
                    Value = -1, ErrorInfo = "Cancelled"
                });
            }
            finally
            {
                if (error == true &&
                    channel != null)
                {
                    channel.Close();
                    if (close_action != null)
                    {
                        close_action.Invoke();
                    }
                }
            }
        }
示例#16
0
        // 装载记录索引
        int LoadIndex(string strLogFilename,
                      out string strError)
        {
            strError = "";

            Stream stream = null;

            try
            {
                stream = File.OpenRead(strLogFilename);
            }
            catch (Exception ex)
            {
                strError = "file '" + strLogFilename + "'open error: " + ex.Message;
                return(-1);
            }

            try
            {
                this.treeView_ber.Nodes.Clear();

                for (long i = 0; ; i++)
                {
                    byte[] len_buffer = new byte[8];

                    int nRet = stream.Read(len_buffer, 0, 8);
                    if (nRet == 0)
                    {
                        break;
                    }
                    if (nRet != 8)
                    {
                        strError = "file format error";
                        return(-1);
                    }

                    long length = BitConverter.ToInt64(len_buffer, 0);

                    if (length == -1)
                    {
                        // 出现了一个未收尾的事项
                        // 把文件最后都算作它的内容
                        length = stream.Length - stream.Position;
                    }

                    IndexInfo info = new IndexInfo();

                    info.index = i;

                    TreeNode node = new TreeNode();

                    if (length == 0)
                    {
                        // 特殊处理
                        node.Text       = i.ToString();
                        node.ImageIndex = 0;
                        node.Tag        = info;
                        this.treeView_ber.Nodes.Add(node);
                        continue;
                    }

                    int direction = stream.ReadByte();

                    long lStartOffs = stream.Position;

                    length--;   // 这是内容长度

                    node.Text = i.ToString();
                    // 方向'
                    string strDirection = "";
                    int    nImageIndex  = 0;
                    if (direction == 0)
                    {
                        strDirection = "none";
                        nImageIndex  = 0;
                    }
                    else if (direction == 1)
                    {
                        strDirection = "client";
                        nImageIndex  = 1;
                    }
                    else if (direction == 2)
                    {
                        strDirection = "server";
                        nImageIndex  = 2;
                    }
                    else
                    {
                        strDirection = "error direction value: " + ((int)direction).ToString();
                        nImageIndex  = 0;
                    }

                    node.Text      += " " + strDirection;
                    node.Text      += " len:" + length.ToString();
                    node.Text      += " offs:" + lStartOffs.ToString();
                    node.ImageIndex = nImageIndex;

                    info.Offs   = lStartOffs;
                    info.Length = length;

                    node.Tag = info;
                    this.treeView_ber.Nodes.Add(node);


                    if (length >= 100 * 1024)
                    {
                        stream.Seek(length, SeekOrigin.Current);
                        info.BerTree = null;
                    }
                    else
                    {
                        byte [] baPackage = new byte[(int)length];
                        stream.Read(baPackage, 0, (int)length);

                        int nParseStart = 0;
                        for (int j = 0; ; j++)
                        {
                            BerTree tree    = new BerTree();
                            int     nTotlen = 0;
                            tree.m_RootNode.BuildPartTree(baPackage,
                                                          nParseStart,
                                                          baPackage.Length,
                                                          out nTotlen);

                            if (j == 0)
                            {
                                TreeNode newnode = new TreeNode();
                                node.Nodes.Add(newnode);

                                FillNodeAndChildren(newnode, tree.m_RootNode.ChildrenCollection[0]);
                            }
                            else
                            {
                                TreeNode newnode = new TreeNode();
                                node.Nodes.Add(newnode);

                                FillNodeAndChildren(newnode, tree.m_RootNode.ChildrenCollection[0]);
                            }

                            nParseStart += nTotlen;
                            if (nParseStart >= baPackage.Length)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            finally
            {
                stream.Close();
            }

            return(0);
        }
示例#17
0
        // 执行初始化
        // 同步模式
        // parameters:
        //      strResultInfo   [out]返回说明初始化结果的文字
        // return Value:
        //      -1  出错
        //      0   成功
        async Task <InitialResult> Initial(
            TargetInfo targetinfo,
            bool bIgnoreReferenceID,
            string reference_id)
        {
            string strResultInfo = "";

            BerTree      tree             = new BerTree();
            INIT_REQUEST struInit_request = new INIT_REQUEST();

            // TargetInfo targetinfo = connection.TargetInfo;

            if (this._channel.Initialized == true)
            {
                return new InitialResult {
                           Value = -1, ErrorInfo = "先前已经初始化过了,不应重复初始化"
                }
            }
            ;                                                                              // 不能重复调用

            struInit_request.m_strReferenceId = reference_id;
            struInit_request.m_strOptions     = "yynnnnnnnnnnnnnnnn"; // "yyynynnyynynnnyn";

            struInit_request.m_lPreferredMessageSize  = 0x100000;     ////16384;
            struInit_request.m_lExceptionalRecordSize = 0x100000;

            if (String.IsNullOrEmpty(targetinfo.UserName) == false)
            {
                struInit_request.m_strID = targetinfo.UserName;

                struInit_request.m_strPassword           = targetinfo.Password;
                struInit_request.m_strGroupID            = targetinfo.GroupID;
                struInit_request.m_nAuthenticationMethod = targetinfo.AuthenticationMethod;
            }
            else
            {
                struInit_request.m_strID                 = "";
                struInit_request.m_strPassword           = "";
                struInit_request.m_strGroupID            = "";
                struInit_request.m_nAuthenticationMethod = -1;
            }

            struInit_request.m_strImplementationId      = "DigitalPlatform";
            struInit_request.m_strImplementationVersion = "1.2.0";
            struInit_request.m_strImplementationName    = "Z3950_library";

            if (targetinfo.CharNegoUTF8 == true)
            {
                struInit_request.m_charNego = new CharsetNeogatiation();
                struInit_request.m_charNego.EncodingLevelOID          = CharsetNeogatiation.Utf8OID; //  "1.0.10646.1.0.8";   // utf-8
                struInit_request.m_charNego.RecordsInSelectedCharsets = (targetinfo.CharNegoRecordsUTF8 == true ? 1 : 0);
            }

            int nRet = tree.InitRequest(struInit_request,
                                        targetinfo.DefaultQueryTermEncoding,
                                        out byte[] baPackage);

            if (nRet == -1)
            {
                return new InitialResult {
                           Value = -1, ErrorInfo = "CBERTree::InitRequest() fail!"
                }
            }
            ;

            if (this._channel.Connected == false)
            {
                this.CloseConnection();

                return(new InitialResult {
                    Value = -1, ErrorInfo = "socket尚未连接或者已经被关闭"
                });
            }



#if DUMPTOFILE
            DeleteFile("initrequest.bin");
            DumpPackage("initrequest.bin",
                        (char *)baPackage.GetData(),
                        baPackage.GetSize());
            DeleteFile("initrequest.txt");
            tree.m_RootNode.DumpToFile("initrequest.txt");
#endif


            RecvResult result = await this._channel.SendAndRecv(
                baPackage);

            if (result.Value == -1)
            {
                return(new InitialResult(result));
            }

#if DUMPTOFILE
            DeleteFile("initresponse.bin");
            DumpPackage("initresponse.bin",
                        (char *)baOutPackage.GetData(),
                        baOutPackage.GetSize());
#endif

            ////////////////////////////////////////////////////////////////
            BerTree tree1 = new BerTree();
            tree1.m_RootNode.BuildPartTree(result.Package,
                                           0,
                                           result.Package.Length,
                                           out int nTotalLen);


#if DUMPTOFILE
            DeleteFile("InitResponse.txt");
            tree1.m_RootNode.DumpDebugInfoToFile("InitResponse.txt");
#endif

            INIT_RESPONSE init_response = new INIT_RESPONSE();
            nRet = BerTree.GetInfo_InitResponse(tree1.GetAPDuRoot(),
                                                ref init_response,
                                                out string strError);
            if (nRet == -1)
            {
                return new InitialResult {
                           Value = -1, ErrorInfo = strError
                }
            }
            ;


            if (bIgnoreReferenceID == false)
            {
                // 可以帮助发现旧版本dp2zserver的错误
                if (struInit_request.m_strReferenceId != init_response.m_strReferenceId)
                {
                    strError = "请求的 reference id [" + struInit_request.m_strReferenceId + "] 和 响应的 reference id [" + init_response.m_strReferenceId + "] 不一致!";
                    return(new InitialResult {
                        Value = -1, ErrorInfo = strError
                    });
                }
            }

            // 2007/11/5检查version和options
            bool bOption_0 = BerTree.GetBit(init_response.m_strOptions,
                                            0);
            if (bOption_0 == false)
            {
                strError = "服务器响应的 option bit 0 表示不支持 search";

                return(new InitialResult {
                    Value = -1, ErrorInfo = strError
                });
            }

            bool bOption_1 = BerTree.GetBit(init_response.m_strOptions,
                                            1);
            if (bOption_1 == false)
            {
                strError = "服务器响应的 option bit 1 表示不支持 present";
                return(new InitialResult {
                    Value = -1, ErrorInfo = strError
                });
            }

            if (init_response.m_nResult != 0)
            {
                strError = "Initial OK";
            }
            else
            {
                strError = "Initial被拒绝。\r\n\r\n错误码 ["
                           + init_response.m_lErrorCode.ToString()
                           + "]\r\n错误消息["
                           + init_response.m_strErrorMessage + "]";

                strResultInfo = BuildInitialResultInfo(init_response);
                return(new InitialResult
                {
                    Value = -1,
                    ErrorInfo = strError,
                    ResultInfo = strResultInfo
                });
            }

            /*
             * this->m_init_strOption = init_response.m_strOptions;
             * this->m_init_lPreferredMessageSize = init_response.m_lPreferredMessageSize;
             * this->m_init_lExceptionalRecordSize = init_response.m_lExceptionalRecordSize;
             * this->m_init_nResult = init_response.m_nResult;
             * */

            this._channel.Initialized = true;

            // 字符集协商
            if (init_response.m_charNego != null &&
                BerTree.GetBit(init_response.m_strOptions, 17) == true)
            {
                if (init_response.m_charNego.EncodingLevelOID == CharsetNeogatiation.Utf8OID)
                {
                    // 临时修改检索词的编码方式。
                    // 但是还无法反映到PropertyDialog上。最好能反馈。
                    targetinfo.DefaultQueryTermEncoding = Encoding.UTF8;
                    targetinfo.Changed = true;

                    if (init_response.m_charNego.RecordsInSelectedCharsets == 1)
                    {
                        this.ForcedRecordsEncoding = Encoding.UTF8;
                    }
                }
            }

            strResultInfo = BuildInitialResultInfo(init_response);
            return(new InitialResult
            {
                Value = 0,
                ErrorInfo = strError,
                ResultInfo = strResultInfo
            });
        }
示例#18
0
        // 检索
        // 本函数每次调用前,最好调用一次 TryInitialize()
        // parameters:
        //      strQuery    Search() 专用的检索式。注意,不是一个检索词那么简单
        //      dbnames     一般是从 targetInfo.DbNames 里面获得。或者从中选择一个数据库名用在这里
        //      strPreferredRecordSyntax 一般是从 targetInfo.PreferredRecordSyntax 获得即可
        // result.Value:
        //		-1	error
        //		0	fail
        //		1	succeed
        // result.ResultCount:
        //      命中结果集内记录条数 (当 result.Value 为 1 时)
        public async Task <SearchResult> Search(
            string strQuery,
            Encoding queryTermEncoding,
            string[] dbnames,
            string strPreferredRecordSyntax,
            string strResultSetName)
        {
            BerTree        tree = new BerTree();
            SEARCH_REQUEST struSearch_request = new SEARCH_REQUEST
            {
                m_dbnames = dbnames
            };

            Debug.Assert(struSearch_request.m_dbnames.Length != 0, "");

            struSearch_request.m_strReferenceId              = this._currentRefID;
            struSearch_request.m_lSmallSetUpperBound         = 0;
            struSearch_request.m_lLargeSetLowerBound         = 1;
            struSearch_request.m_lMediumSetPresentNumber     = 0;
            struSearch_request.m_nReplaceIndicator           = 1;
            struSearch_request.m_strResultSetName            = strResultSetName; // "default";
            struSearch_request.m_strSmallSetElementSetNames  = "";
            struSearch_request.m_strMediumSetElementSetNames = "";
            struSearch_request.m_strPreferredRecordSyntax    = strPreferredRecordSyntax; //  ZTargetControl.GetLeftValue(this.TargetInfo.PreferredRecordSyntax);   // BerTree.MARC_SYNTAX;
            struSearch_request.m_strQuery          = strQuery;
            struSearch_request.m_nQuery_type       = 1;
            struSearch_request.m_queryTermEncoding = queryTermEncoding;


            // m_search_response.m_lErrorCode = 0;
            byte[] baPackage = null;

            try
            {
                // 这里可能抛出异常
                tree.SearchRequest(struSearch_request,
                                   out baPackage);
            }
            catch (Exception ex)
            {
                return(new SearchResult {
                    Value = -1, ErrorInfo = "CBERTree::SearchRequest() Exception: " + ex.Message
                });
            }

            if (this._channel.Connected == false)
            {
                this.CloseConnection();
                return(new SearchResult {
                    Value = -1, ErrorInfo = "socket尚未连接或者已经被关闭"
                });
            }

#if DUMPTOFILE
            string strBinFile = this.MainForm.DataDir + "\\searchrequest.bin";
            File.Delete(strBinFile);
            DumpPackage(strBinFile,
                        baPackage);
            string strLogFile = this.MainForm.DataDir + "\\searchrequest.txt";
            File.Delete(strLogFile);
            tree.m_RootNode.DumpToFile(strLogFile);
#endif


#if NO
            nRet = CheckConnect(
                out strError);
            if (nRet == -1)
            {
                return(-1);
            }
#endif

            BerTree tree1 = new BerTree();

            {
                RecvResult result = await this._channel.SendAndRecv(
                    baPackage);

                if (result.Value == -1)
                {
                    return(new SearchResult(result));
                }

#if NO
#if DEBUG
                if (nRet == 0)
                {
                    Debug.Assert(strError == "", "");
                }
#endif
#endif

#if DUPMTOFILE
                DeleteFile("searchresponse.bin");
                DumpPackage("searchresponse.bin",
                            (char *)baOutPackage.GetData(),
                            baOutPackage.GetSize());
#endif

                tree1.m_RootNode.BuildPartTree(result.Package,
                                               0,
                                               result.Package.Length,
                                               out int nTotalLen);
            }

            SEARCH_RESPONSE search_response = new SEARCH_RESPONSE();
            int             nRet            = BerTree.GetInfo_SearchResponse(tree1.GetAPDuRoot(),
                                                                             ref search_response,
                                                                             true,
                                                                             out string strError);
            if (nRet == -1)
            {
                return new SearchResult {
                           Value = -1, ErrorInfo = strError
                }
            }
            ;

#if DUMPTOFILE
            DeleteFile("SearchResponse.txt");
            tree1.m_RootNode.DumpDebugInfoToFile("SearchResponse.txt");
#endif
            {
                SearchResult result = new SearchResult();

                result.ResultCount = (int)search_response.m_lResultCount;

                if (search_response.m_nSearchStatus != 0)   // 不一定是1
                {
                    result.Value = 1;
                    return(result);
                }

                result.ErrorInfo = "Search Fail: diagRecords:\r\n" + search_response.m_diagRecords.GetMessage();
                result.Value     = 0; // search fail
                return(result);
            }
        }
示例#19
0
        // 处理Server可能发来的Close
        // return:
        //      -1  error
        //      0   不是Close
        //      1   是Close,已经迫使ZChannel处于尚未初始化状态
        int CheckServerCloseRequest(
            ZConnection connection,
            out string strMessage,
            out string strError)
        {
            strMessage = "";
            strError = "";

            if (connection.ZChannel.DataAvailable == false)
                return 0;

            int nRecvLen = 0;
            byte [] baPackage = null;
            int nRet = connection.ZChannel.RecvTcpPackage(
                        out baPackage,
                        out nRecvLen,
                        out strError);
            if (nRet == -1)
                return -1;

            BerTree tree1 = new BerTree();
            int nTotlen = 0;

            tree1.m_RootNode.BuildPartTree(baPackage,
                0,
                baPackage.Length,
                out nTotlen);

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

            CLOSE_REQUEST closeStruct = new CLOSE_REQUEST();
            nRet = BerTree.GetInfo_closeRequest(
                tree1.GetAPDuRoot(),
                ref closeStruct,
                out strError);
            if (nRet == -1)
                return -1;

            strMessage = closeStruct.m_strDiagnosticInformation;

            /*
            this.ZChannel.CloseSocket();
            this.ZChannel.Initialized = false;  // 迫使重新初始化
            if (this.CurrentTargetInfo != null)
                this.CurrentTargetInfo.OfflineServerIcon();
             * */
            connection.CloseConnection();

            return 1;
        }
示例#20
0
        // 处理一个通道的通讯活动
        public async void HandleClient(TcpClient tcpClient,
                                       CancellationToken token)
        {
            ZServerChannel channel = _zChannels.Add(tcpClient);

            // 允许对 channel 做额外的初始化
            if (this.ChannelOpened != null)
            {
                this.ChannelOpened(channel, new EventArgs());
            }
            try
            {
                //List<byte> cache = new List<byte>();
                string ip = "";
                //Stream inputStream = tcpClient.GetStream();
                //Stream outputStream = tcpClient.GetStream();

                try
                {
                    ip = GetClientIP(tcpClient);
                    channel.Touch();

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                        BerTree request = await ZProcessor.GetIncomingRequest(tcpClient);

                        if (request == null)
                        {
                            Console.WriteLine("client close on request " + i);
                            break;
                        }
                        Console.WriteLine("request " + i);

                        channel.Touch();

                        byte[] response = null;
                        if (this.ProcessRequest == null)
                        {
                            response = await DefaultProcessRequest(channel, request);
                        }
                        else
                        {
                            ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                            e.Request = request;
                            this.ProcessRequest(channel, e);
                            response = e.Response;
                        }

                        channel.Touch();

                        // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                        Result result = await ZProcessor.SendResponse(response, tcpClient);

                        channel.Touch();
                        if (result.Value == -1)
                        {
                            Console.WriteLine("error on response " + i + ": " + result.ErrorInfo);
                            break;
                        }

                        i++;
                    }
                }
                catch (Exception ex)
                {
                    // 2016/11/14
                    ZManager.Log?.Error("ip:" + ip + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex));
                }
                finally
                {
#if NO
                    outputStream.Flush();
                    outputStream.Close();
                    outputStream = null;

                    inputStream.Close();
                    inputStream = null;
#endif

                    // tcpClient.Close();

                    // 清除全局结果集
                }
            }
            finally
            {
                _zChannels.Remove(channel);
#if NO
                if (this.ChannelClosed != null)
                {
                    ChannelClosedEventArgs e = new ChannelClosedEventArgs();
                    e.Channel = channel;
                    this.ChannelClosed(channel, e);
                }
#endif
                channel.Close();
            }
        }
示例#21
0
文件: Session.cs 项目: renyh1013/dp2
        // 编码(构造) Present响应包
        int Encode_PresentResponse(PresentRequestInfo info,
            out byte[] baPackage)
        {
            baPackage = null;
            int nRet = 0;
            string strError = "";

            DiagFormat diag = null;

            BerTree tree = new BerTree();
            BerNode root = null;

            string strResultSetName = info.m_strResultSetID;
            if (String.IsNullOrEmpty(strResultSetName) == true)
                strResultSetName = "default";
            long lStart = info.m_lResultSetStartPoint - 1;
            long lNumber = info.m_lNumberOfRecordsRequested;

            long lPerCount = lNumber;

            long lHitCount = 0;

            List<string> paths = new List<string>();

            int nPresentStatus = 5; // failed

            // 获取结果集中需要部分的记录path
            long lOffset = lStart;
            int nCount = 0;
            for (; ; )
            {
                DigitalPlatform.LibraryClient.localhost.Record[] searchresults = null;

                long lRet = this._channel.GetSearchResult(
                    null,   // stop,
                    strResultSetName,   // strResultSetName
                    lOffset,
                    lPerCount,
                    "id",
                    "zh",   // this.Lang,
                    out searchresults,
                    out strError);
                /*
                // 测试获取结果集失败的情况,返回非代理诊断记录
                lRet = -1;
                strError = "测试检索错误信息!";
                 * */

                if (lRet == -1)
                {
                    SetPresentDiagRecord(ref diag,
                        2,  // temporary system error
                        strError);
                    break;
                }
                if (lRet == 0)
                {
                    // goto ERROR1 ?
                }

                lHitCount = lRet;   // 顺便得到命中记录总条数

                // 转储
                for (int i = 0; i < searchresults.Length; i++)
                {
                    paths.Add(searchresults[i].Path);
                }

                lOffset += searchresults.Length;
                lPerCount -= searchresults.Length;
                nCount += searchresults.Length;

                if (lOffset >= lHitCount
                    || lPerCount <= 0
                    || nCount >= lNumber)
                {
                    // 
                    break;
                }
            }

            // TODO: 需要注意多个错误是否形成多个diag记录?V2不允许这样,V3允许这样
            if (lHitCount < info.m_lResultSetStartPoint
                && diag == null)
            {
                strError = "start参数值 "
                    + info.m_lResultSetStartPoint
                    + " 超过结果集中记录总数 "
                    + lHitCount;
                // return -1;  // 如果表示错误状态?
                SetPresentDiagRecord(ref diag,
                    13,  // Present request out-of-range
                    strError);
            }

            int MAX_PRESENT_RECORD = 100;

            // 限制每次 present 的记录数量
            if (lNumber > MAX_PRESENT_RECORD)
                lNumber = MAX_PRESENT_RECORD;

            long nNextResultSetPosition = 0;

            // 
            if (lHitCount < (lStart - 1) + lNumber)
            {
                // 是 present 错误,但还可以调整 lNumber
                lNumber = lHitCount - (lStart - 1);
                nNextResultSetPosition = 0;
            }
            else
            {
                //
                nNextResultSetPosition = lStart + lNumber + 1;
            }

            root = tree.m_RootNode.NewChildConstructedNode(
                BerTree.z3950_presentResponse,
                BerNode.ASN1_CONTEXT);

            // reference id
            if (String.IsNullOrEmpty(info.m_strReferenceId) == false)
            {
                root.NewChildCharNode(BerTree.z3950_ReferenceId,
                    BerNode.ASN1_CONTEXT,
                    Encoding.UTF8.GetBytes(info.m_strReferenceId));
            }

            List<RetrivalRecord> records = new List<RetrivalRecord>();

            // 获取要返回的MARC记录
            if (diag == null)
            {

                // 记录编码格式为 GRS-1 (generic-record-syntax-1) :
                //		EXTERNAL 
                //			--- OID (Object Identifier)
                //			--- MARC (OCTET STRING)
                //	m_strOID = _T("1.2.840.10003.5.1");  // OID of UNIMARC
                //	m_strOID = _T("1.2.840.10003.5.10"); // OID of USMARC //
                // 需要建立一个数据库名和oid的对照表,方面快速取得数据库MARC syntax OID

                // TODO: 编码过程中,可能会发现记录太多,总尺寸超过Initial中规定的prefered message size。
                // 这样需要减少返回的记录数量。这样,就需要先做这里的循环,后构造另外几个参数
                int nSize = 0;
                for (int i = 0; i < (int)lNumber; i++)
                {
                    // 编码 N 条 MARC 记录
                    //
                    // if (m_bStop) return false;

                    // 取出数据库指针
                    // lStart 不是 0 起点的
                    string strPath = paths[i];

                    // 解析出数据库名和ID
                    string strDbName = Global.GetDbName(strPath);
                    string strRecID = Global.GetRecordID(strPath);

                    // 如果取得的是xml记录,则根元素可以看出记录的marc syntax,进一步可以获得oid;
                    // 如果取得的是MARC格式记录,则需要根据数据库预定义的marc syntax来看出oid了
                    string strMarcSyntaxOID = GetMarcSyntaxOID(strDbName);

                    byte[] baMARC = null;

                    RetrivalRecord record = new RetrivalRecord();
                    record.m_strDatabaseName = strDbName;

                    // 根据书目库名获得书目库属性对象
                    BiblioDbProperty prop = this._service.GetDbProperty(
                        strDbName,
                        false);

                    nRet = GetMARC(strPath,
                        info.m_elementSetNames,
                        prop != null ? prop.AddField901 : false,
                        out baMARC,
                        out strError);

                    /*
                    // 测试记录群中包含诊断记录
                    if (i == 1)
                    {
                        nRet = -1;
                        strError = "测试获取记录错误";
                    }*/
                    if (nRet == -1)
                    {
                        record.m_surrogateDiagnostic = new DiagFormat();
                        record.m_surrogateDiagnostic.m_strDiagSetID = "1.2.840.10003.4.1";
                        record.m_surrogateDiagnostic.m_nDiagCondition = 14;  // system error in presenting records
                        record.m_surrogateDiagnostic.m_strAddInfo = strError;
                    }
                    else if (nRet == 0)
                    {
                        record.m_surrogateDiagnostic = new DiagFormat();
                        record.m_surrogateDiagnostic.m_strDiagSetID = "1.2.840.10003.4.1";
                        record.m_surrogateDiagnostic.m_nDiagCondition = 1028;  // record deleted
                        record.m_surrogateDiagnostic.m_strAddInfo = strError;
                    }
                    else if (String.IsNullOrEmpty(strMarcSyntaxOID) == true)
                    {
                        // 根据数据库名无法获得marc syntax oid。可能是虚拟库检索命中记录所在的物理库没有在dp2zserver.xml中配置。
                        record.m_surrogateDiagnostic = new DiagFormat();
                        record.m_surrogateDiagnostic.m_strDiagSetID = "1.2.840.10003.4.1";
                        record.m_surrogateDiagnostic.m_nDiagCondition = 109;  // database unavailable // 似乎235:database dos not exist也可以
                        record.m_surrogateDiagnostic.m_strAddInfo = "根据数据库名 '" + strDbName + "' 无法获得marc syntax oid";
                    }
                    else
                    {
                        record.m_external = new External();
                        record.m_external.m_strDirectRefenerce = strMarcSyntaxOID;
                        record.m_external.m_octectAligned = baMARC;
                    }

                    nSize += record.GetPackageSize();

                    if (i == 0)
                    {
                        // 连一条记录也放不下
                        if (nSize > this._lExceptionalRecordSize)
                        {
                            Debug.Assert(diag == null, "");
                            SetPresentDiagRecord(ref diag,
                                17, // record exceeds Exceptional_record_size
                                "记录尺寸 " + nSize.ToString() + " 超过 Exceptional_record_size " + this._lExceptionalRecordSize.ToString());
                            lNumber = 0;
                            break;
                        }
                    }
                    else
                    {
                        if (nSize >= this._lPreferredMessageSize)
                        {
                            // 调整返回的记录数
                            lNumber = i;
                            break;
                        }
                    }

                    records.Add(record);
                }
            }


            // numberOfRecordsReturned
            root.NewChildIntegerNode(BerTree.z3950_NumberOfRecordsReturned, // 24
                BerNode.ASN1_CONTEXT,   // ASN1_PRIMITIVE BUG!!!
                BitConverter.GetBytes((long)lNumber));

            if (diag != null)
                nPresentStatus = 5;
            else
                nPresentStatus = 0;

            // nextResultSetPosition
            // if 0, that's end of the result set
            // else M+1, M is 最后一次 present response 的最后一条记录在 result set 中的 position
            root.NewChildIntegerNode(BerTree.z3950_NextResultSetPosition, // 25
                BerNode.ASN1_CONTEXT,   // ASN1_PRIMITIVE BUG!!!
                BitConverter.GetBytes((long)nNextResultSetPosition));

            // presentStatus
            // success      (0),
            // partial-1    (1),
            // partial-2    (2),
            // partial-3    (3),
            // partial-4    (4),
            // failure      (5).
            root.NewChildIntegerNode(BerTree.z3950_presentStatus, // 27
                BerNode.ASN1_CONTEXT,   // ASN1_PRIMITIVE BUG!!!
               BitConverter.GetBytes((long)nPresentStatus));


            // 诊断记录
            if (diag != null)
            {
                BerNode nodeDiagRoot = root.NewChildConstructedNode(BerTree.z3950_nonSurrogateDiagnostic,    // 130
                    BerNode.ASN1_CONTEXT);

                diag.BuildBer(nodeDiagRoot);

                /*
                nodeDiagRoot.NewChildOIDsNode(6,
                    BerNode.ASN1_UNIVERSAL,
                    diag.m_strDiagSetID);   // "1.2.840.10003.4.1"

                nodeDiagRoot.NewChildIntegerNode(2,
                    BerNode.ASN1_UNIVERSAL,
                    BitConverter.GetBytes((long)diag.m_nDiagCondition));

                if (String.IsNullOrEmpty(diag.m_strAddInfo) == false)
                {
                    nodeDiagRoot.NewChildCharNode(26,
                        BerNode.ASN1_UNIVERSAL,
                        Encoding.UTF8.GetBytes(diag.m_strAddInfo));
                }
                 * */
            }


            // 如果 present 是非法的,到这里打包完成,可以返回了
            if (0 != nPresentStatus)
                goto END1;

            // 编码记录BER树

            // 以下为 present 成功时,打包返回记录。
            // present success
            // presRoot records child, constructed (choice of ... ... optional)
            // if present fail, then may be no records 'node'
            // Records ::= CHOICE {
            //		responseRecords              [28]   IMPLICIT SEQUENCE OF NamePlusRecord,
            //		nonSurrogateDiagnostic       [130]  IMPLICIT DefaultDiagFormat,
            //		multipleNonSurDiagnostics    [205]  IMPLICIT SEQUENCE OF DiagRec} 

            // 当 present 成功时,response 选择了 NamePlusRecord (数据库名 + 记录)
            BerNode node = root.NewChildConstructedNode(BerTree.z3950_dataBaseOrSurDiagnostics,    // 28
                            BerNode.ASN1_CONTEXT);

            for (int i = 0; i < records.Count; i++)
            {
                RetrivalRecord record = records[i];

                record.BuildNamePlusRecord(node);
            }

        END1:

            baPackage = null;
            root.EncodeBERPackage(ref baPackage);

            return 0;
        }
示例#22
0
文件: Session.cs 项目: renyh1013/dp2
        // 2007/7/18
        //	 build a z39.50 Init response
        public static int Encode_InitialResponse(InitResponseInfo info,
            out byte[] baPackage)
        {
            baPackage = null;

            BerNode root = null;

            BerTree tree = new BerTree();

            root = tree.m_RootNode.NewChildConstructedNode(BerTree.z3950_initResponse,
                BerNode.ASN1_CONTEXT);

            if (String.IsNullOrEmpty(info.m_strReferenceId) == false)
            {
                root.NewChildCharNode(BerTree.z3950_ReferenceId,
                    BerNode.ASN1_CONTEXT,
                    Encoding.UTF8.GetBytes(info.m_strReferenceId));
            }

            root.NewChildBitstringNode(BerTree.z3950_ProtocolVersion,   // 3
                BerNode.ASN1_CONTEXT,
                "yy");

            /* option
         search                 (0), 
         present                (1), 
         delSet                 (2),
         resourceReport         (3),
         triggerResourceCtrl    (4),
         resourceCtrl           (5), 
         accessCtrl             (6),
         scan                   (7),
         sort                   (8), 
         --                     (9) (reserved)
         extendedServices       (10),
         level-1Segmentation    (11),
         level-2Segmentation    (12),
         concurrentOperations   (13),
         namedResultSets        (14)
            15 Encapsulation  Z39.50-1995 Amendment 3: Z39.50 Encapsulation 
            16 resultCount parameter in Sort Response  See Note 8 Z39.50-1995 Amendment 1: Add resultCount parameter to Sort Response  
            17 Negotiation Model  See Note 9 Model for Z39.50 Negotiation During Initialization  
            18 Duplicate Detection See Note 1  Z39.50 Duplicate Detection Service  
            19 Query type 104 
*/
            root.NewChildBitstringNode(BerTree.z3950_Options,   // 4
                BerNode.ASN1_CONTEXT,
                info.m_strOptions);    // "110000000000001"

            root.NewChildIntegerNode(BerTree.z3950_PreferredMessageSize,    // 5
                BerNode.ASN1_CONTEXT,
                BitConverter.GetBytes((long)info.m_lPreferredMessageSize));

            root.NewChildIntegerNode(BerTree.z3950_ExceptionalRecordSize,   // 6
                BerNode.ASN1_CONTEXT,
                BitConverter.GetBytes((long)info.m_lExceptionalRecordSize));

            // 2007/11/7 原来这个事项曾经位置不对,现在调整到这里
            // bool
            root.NewChildIntegerNode(BerTree.z3950_result,  // 12
                BerNode.ASN1_CONTEXT,
                BitConverter.GetBytes((long)info.m_nResult));


            root.NewChildCharNode(BerTree.z3950_ImplementationId,   // 110
                BerNode.ASN1_CONTEXT,
                Encoding.UTF8.GetBytes(info.m_strImplementationId));

            root.NewChildCharNode(BerTree.z3950_ImplementationName, // 111
                BerNode.ASN1_CONTEXT,
                Encoding.UTF8.GetBytes(info.m_strImplementationName));

            root.NewChildCharNode(BerTree.z3950_ImplementationVersion,  // 112
                BerNode.ASN1_CONTEXT,
                Encoding.UTF8.GetBytes(info.m_strImplementationVersion));  // "3"


            // userInformationField
            if (info.UserInfoField != null)
            {
                BerNode nodeUserInfoRoot = root.NewChildConstructedNode(BerTree.z3950_UserInformationField,    // 11
                    BerNode.ASN1_CONTEXT);
                info.UserInfoField.Build(nodeUserInfoRoot);
            }

            if (info.m_charNego != null)
            {
                info.m_charNego.EncodeResponse(root);
            }

            baPackage = null;
            root.EncodeBERPackage(ref baPackage);

            return 0;
        }
示例#23
0
        // parameters:
        //      strResultInfo   [out]返回说明初始化结果的文字
        int DoInitial(
            ZConnection connection,
            out string strResultInfo,
            out string strError)
        {
            strResultInfo = "";
            strError = "";

            byte[] baPackage = null;
            BerTree tree = new BerTree();
            INIT_REQUEST struInit_request = new INIT_REQUEST();
            int nRet;
            int nRecvLen;

            TargetInfo targetinfo = connection.TargetInfo;

            if (connection.ZChannel.Initialized == true)
            {
                strError = "Already Initialized";
                goto ERROR1;
            }

            struInit_request.m_strReferenceId = this.CurrentRefID;  //  "0";!!!
            struInit_request.m_strOptions = "yynnnnnnnnnnnnnnnn";   // "yyynynnyynynnnyn";

            struInit_request.m_lPreferredMessageSize = 0x100000; ////16384;
            struInit_request.m_lExceptionalRecordSize = 0x100000;

            if (String.IsNullOrEmpty(targetinfo.UserName) == false)
            {
                struInit_request.m_strID = targetinfo.UserName;
                struInit_request.m_strPassword = targetinfo.Password;
                struInit_request.m_strGroupID = targetinfo.GroupID;
                struInit_request.m_nAuthenticationMethod = targetinfo.AuthenticationMethod;
            }
            else
            {
                struInit_request.m_strID = "";
                struInit_request.m_strPassword = "";
                struInit_request.m_strGroupID = "";
                struInit_request.m_nAuthenticationMethod = -1;
            }

            /*
            struInit_request.m_strImplementationId = "81";    // "81";
            struInit_request.m_strImplementationVersion = "2.0.3 WIN32 Debug";
            struInit_request.m_strImplementationName = "Index Data/YAZ";
             * */

            struInit_request.m_strImplementationId = "DigitalPlatform";
            struInit_request.m_strImplementationVersion = "1.1.0";
            struInit_request.m_strImplementationName = "dp2Catalog";

            if (targetinfo.CharNegoUTF8 == true)
            {
                struInit_request.m_charNego = new CharsetNeogatiation();
                struInit_request.m_charNego.EncodingLevelOID = CharsetNeogatiation.Utf8OID; //  "1.0.10646.1.0.8";   // utf-8
                struInit_request.m_charNego.RecordsInSelectedCharsets = (targetinfo.CharNegoRecordsUTF8 == true ? 1 : 0);
            }

            nRet = tree.InitRequest(struInit_request,
                   targetinfo.DefaultQueryTermEncoding,
                    out baPackage);
            if (nRet == -1)
            {
                strError = "CBERTree::InitRequest() fail!";
                goto ERROR1;
            }

            if (connection.ZChannel.Connected == false)
            {
                strError = "socket尚未连接或者已经被关闭";
                goto ERROR1;
            }


#if DUMPTOFILE
	DeleteFile("initrequest.bin");
	DumpPackage("initrequest.bin",
				(char *)baPackage.GetData(),
				baPackage.GetSize());
	DeleteFile ("initrequest.txt");
	tree.m_RootNode.DumpToFile("initrequest.txt");
#endif

            /*
            nRet = this.ZChannel.SendTcpPackage(
                baPackage,
                baPackage.Length,
                out strError);
            if (nRet == -1 || nRet == 1)
            {
                // CloseZAssociation();
                return -1;
            }

            baPackage = null;
            nRet = this.ZChannel.RecvTcpPackage(
                        out baPackage,
                        out nRecvLen,
                        out strError);
            if (nRet == -1)
            {
                // CloseZAssociation();
                return -1;
            }
             * */

            byte[] baOutPackage = null;
            nRet = connection.ZChannel.SendAndRecv(
                baPackage,
                out baOutPackage,
                out nRecvLen,
                out strError);
            if (nRet == -1)
            {
                goto ERROR1;
            }



#if DUMPTOFILE
	DeleteFile("initresponse.bin");
	DumpPackage("initresponse.bin",
				(char *)baOutPackage.GetData(),
				baOutPackage.GetSize());
#endif

            ////////////////////////////////////////////////////////////////
            BerTree tree1 = new BerTree();
            int nTotlen = 0;

            tree1.m_RootNode.BuildPartTree(baOutPackage,
                0,
                baOutPackage.Length,
                out nTotlen);


#if DUMPTOFILE
	DeleteFile("InitResponse.txt"); 
	tree1.m_RootNode.DumpDebugInfoToFile("InitResponse.txt");
#endif

            /*
	nRet = FitDebugInfo_InitResponse(&tree1,
							  strError);
	if (nRet == -1) {
		return -1;
	}
	*/


            INIT_RESPONSE init_response = new INIT_RESPONSE();
            nRet = BerTree.GetInfo_InitResponse(tree1.GetAPDuRoot(),
                                 ref init_response,
                                 out strError);
            if (nRet == -1)
            {
                goto ERROR1;
            }

            if (targetinfo.IgnoreReferenceID == false)
            {
                // 2007/11/2。可以帮助发现旧版本dp2zserver的错误
                if (struInit_request.m_strReferenceId != init_response.m_strReferenceId)
                {
                    strError = "请求的 reference id [" + struInit_request.m_strReferenceId + "] 和 响应的 reference id [" + init_response.m_strReferenceId + "] 不一致!";
                    goto ERROR1;
                }
            }


            if (init_response.m_nResult != 0)
            {
                strError = "Initial OK";
            }
            else
            {
                strError = "Initial被拒绝。\r\n\r\n错误码 ["
                    + init_response.m_lErrorCode.ToString()
                    + "]\r\n错误消息["
                    + init_response.m_strErrorMessage + "]";

                strResultInfo = ZConnection.BuildInitialResultInfo(init_response);
                return -1;
            }

            /*
	this->m_init_strOption = init_response.m_strOptions;
	this->m_init_lPreferredMessageSize = init_response.m_lPreferredMessageSize;
	this->m_init_lExceptionalRecordSize = init_response.m_lExceptionalRecordSize;
	this->m_init_nResult = init_response.m_nResult;
             * */

            connection.ZChannel.Initialized = true;

            // 字符集协商
            if (init_response.m_charNego != null
                && BerTree.GetBit(init_response.m_strOptions, 17) == true)
            {
                if (init_response.m_charNego.EncodingLevelOID == CharsetNeogatiation.Utf8OID)
                {
                    // 临时修改检索词的编码方式。
                    // 但是还无法反映到PropertyDialog上。最好能反馈。
                    targetinfo.DefaultQueryTermEncoding = Encoding.UTF8;
                    targetinfo.Changed = true;

                    if (init_response.m_charNego.RecordsInSelectedCharsets == 1)
                        connection.ForcedRecordsEncoding = Encoding.UTF8;
                }
            }

            strResultInfo = ZConnection.BuildInitialResultInfo(init_response);

            return 0;
        ERROR1:
            strResultInfo = strError;
            return -1;
        }
示例#24
0
        // 装载记录索引
        int LoadIndex(string strLogFilename,
            out string strError)
        {
            strError = "";

            Stream stream = null;

            try
            {
                stream = File.OpenRead(strLogFilename);
            }
            catch (Exception ex)
            {
                strError = "file '" + strLogFilename + "'open error: " + ex.Message;
                return -1;
            }

            try
            {
                this.treeView_ber.Nodes.Clear();

                for (long i = 0; ; i++)
                {
                    byte[] len_buffer = new byte[8];

                    int nRet = stream.Read(len_buffer, 0, 8);
                    if (nRet == 0)
                        break;
                    if (nRet != 8)
                    {
                        strError = "file format error";
                        return -1;
                    }

                    long length = BitConverter.ToInt64(len_buffer, 0);

                    if (length == -1)
                    {
                        // 出现了一个未收尾的事项
                        // 把文件最后都算作它的内容
                        length = stream.Length - stream.Position;
                    }

                    IndexInfo info = new IndexInfo();

                    info.index = i;

                    TreeNode node = new TreeNode();

                    if (length == 0)
                    {
                        // 特殊处理
                        node.Text = i.ToString();
                        node.ImageIndex = 0;
                        node.Tag = info;
                        this.treeView_ber.Nodes.Add(node);
                        continue;
                    }

                    int direction = stream.ReadByte();

                    long lStartOffs = stream.Position;

                    length--;   // 这是内容长度

                    node.Text = i.ToString();
                    // 方向'
                    string strDirection = "";
                    int nImageIndex = 0;
                    if (direction == 0)
                    {
                        strDirection = "none";
                        nImageIndex = 0;
                    }
                    else if (direction == 1)
                    {
                        strDirection = "client";
                        nImageIndex = 1;
                    }
                    else if (direction == 2)
                    {
                        strDirection = "server";
                        nImageIndex = 2;
                    }
                    else
                    {
                        strDirection = "error direction value: " + ((int)direction).ToString();
                        nImageIndex = 0;
                    }

                    node.Text += " " + strDirection;
                    node.Text += " len:" + length.ToString();
                    node.Text += " offs:" + lStartOffs.ToString();
                    node.ImageIndex = nImageIndex;

                    info.Offs = lStartOffs;
                    info.Length = length;

                    node.Tag = info;
                    this.treeView_ber.Nodes.Add(node);


                    if (length >= 100*1024)
                    {
                        stream.Seek(length, SeekOrigin.Current);
                        info.BerTree = null;
                    }
                    else {
                        byte [] baPackage = new byte[(int)length];
                        stream.Read(baPackage, 0, (int)length);

                        int nParseStart = 0;
                        for (int j=0; ;j++ )
                        {
                            BerTree tree = new BerTree();
                            int nTotlen = 0;
                            tree.m_RootNode.BuildPartTree(baPackage,
                                nParseStart,
                                baPackage.Length,
                                out nTotlen);

                            if (j == 0)
                            {
                                TreeNode newnode = new TreeNode();
                                node.Nodes.Add(newnode);

                                FillNodeAndChildren(newnode, tree.m_RootNode.ChildrenCollection[0]);
                            }
                            else
                            {
                                TreeNode newnode = new TreeNode();
                                node.Nodes.Add(newnode);

                                FillNodeAndChildren(newnode, tree.m_RootNode.ChildrenCollection[0]);
                            }

                            nParseStart += nTotlen;
                            if (nParseStart >= baPackage.Length)
                                break;
                        }
                    }
                }
            }
            finally
            {
                stream.Close();
            }

            return 0;
        }
示例#25
0
        // 处理一个通道的通讯活动
        public virtual void HandleClient(TcpClient tcpClient,
                                         Action close_action,
                                         CancellationToken token)
        {
#if NO
            ZServerChannel channel = _zChannels.Add(tcpClient);
            // 允许对 channel 做额外的初始化
            if (this.ChannelOpened != null)
            {
                this.ChannelOpened(channel, new EventArgs());
            }
            try
            {
                string ip = "";

                try
                {
                    ip = GetClientIP(tcpClient);
                    channel.Touch();

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }
                        // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                        BerTree request = await ZProcessor.GetIncomingRequest(tcpClient);

                        if (request == null)
                        {
                            Console.WriteLine("client close on request " + i);
                            break;
                        }
                        Console.WriteLine("request " + i);

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        byte[] response = null;
                        if (this.ProcessRequest == null)
                        {
                            response = await DefaultProcessRequest(channel, request);
                        }
                        else
                        {
                            ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                            e.Request = request;
                            this.ProcessRequest(channel, e);
                            response = e.Response;
                        }

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                        Result result = await SendResponse(response, tcpClient);

                        channel.Touch();
                        if (result.Value == -1)
                        {
                            Console.WriteLine("error on response " + i + ": " + result.ErrorInfo);
                            break;
                        }

                        i++;
                    }
                }
                catch (Exception ex)
                {
                    string strError = "ip:" + ip + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex);
                    ZManager.Log?.Error(strError);
                    // Console.WriteLine(strError);
                }
                finally
                {
                    // tcpClient.Close();
                    // 清除全局结果集
                }
            }
            finally
            {
                _zChannels.Remove(channel);
                channel.Close();
                close_action.Invoke();
            }
#endif
        }
示例#26
0
        // Pipeline 版本
        // 处理一个通道的通讯活动
        public async override void HandleClient(TcpClient tcpClient,
                                                Action close_action,
                                                CancellationToken token)
        {
            List <byte> cache = new List <byte>();

            ZServerChannel channel = _tcpChannels.Add(tcpClient, () => { return(new ZServerChannel()); }) as ZServerChannel;

            // 允许对 channel 做额外的初始化
            if (this.ChannelOpened != null)
            {
                this.ChannelOpened(channel, new EventArgs());
            }
            try
            {
                string name = "";
                string ip   = "";

                Task <Result> task = null;
                try
                {
                    name = channel.GetDebugName(tcpClient);
                    ip   = TcpServer.GetClientIP(tcpClient);

                    channel.Touch();

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                        BerTree request = await ZProcessor.GetIncomingRequest(
                            cache,
                            tcpClient,
                            () => channel.Touch()).ConfigureAwait(false);  // 2018/10/10 add configure

                        if (request == null)
                        {
                            Console.WriteLine("client close on request " + i);
                            break;
                        }
                        Console.WriteLine("request " + i);

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        // 如果前一轮的任务还没有完成,这里等待
                        if (task != null)
                        {
                            Result result = task.Result;
                            if (result.Value == -1)
                            {
                                return;
                            }
                            task = null;
                        }

                        task = Task.Run(() =>
                                        ProcessAndResponse(
                                            tcpClient,
                                            close_action,
                                            channel,
                                            request,
                                            token));

                        i++;
                    }
                }
                catch (Exception ex)
                {
#if NO
                    if (ex.InnerException != null && ex.InnerException is ObjectDisposedException)
                    {
                        // 这种情况一般是 server 主动清理闲置通道导致的,不记入日志
                    }
                    else if (ex is ObjectDisposedException)
                    {
                        // 这种情况一般是 client close 通道导致,不记入日志
                    }
#endif

#if NO
                    if (GetException(ex, typeof(ObjectDisposedException)) != null)
                    {
                        return;
                    }

                    SocketException socket_ex = (SocketException)GetException(ex, typeof(SocketException));
                    if (socket_ex != null && socket_ex.SocketErrorCode == SocketError.ConnectionReset)
                    {
                        return;
                    }

                    {
                        string strName = "ip:" + ip
                                         + channel == null ? "(null)" : " channel:" + channel.GetHashCode();
                        string strError = strName + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex);
                        LibraryManager.Log?.Error(strError);
                        // Console.WriteLine(strError);
                    }
#endif
                    if (ex is UnknownApduException ||
                        ex is BadApduException)
                    {
                        IpTable.SetInBlackList(ip, TimeSpan.FromHours(1));
                        LibraryManager.Log?.Info(string.Format("IP 地址 {0} 已被加入黑名单,时限一个小时", ip));
                    }

                    LogException(ex, channel, name);
                }
                finally
                {
#if NO
                    outputStream.Flush();
                    outputStream.Close();
                    outputStream = null;

                    inputStream.Close();
                    inputStream = null;
#endif

                    // tcpClient.Close();

                    // 清除全局结果集
                    if (task != null)
                    {
                        // TODO: 要想办法立即终止检索和响应过程
                    }
                }
            }
            finally
            {
                _tcpChannels.Remove(channel);
#if NO
                if (this.ChannelClosed != null)
                {
                    ChannelClosedEventArgs e = new ChannelClosedEventArgs();
                    e.Channel = channel;
                    this.ChannelClosed(channel, e);
                }
#endif
                channel.Close();
                if (close_action != null)
                {
                    close_action.Invoke();
                }
            }
        }
示例#27
0
        // 解释包
        void menuItem_explainContent_Click(object sender,
                                           EventArgs e)
        {
            TreeNode node = this.treeView_ber.SelectedNode;

            if (node == null)
            {
                MessageBox.Show(this, "尚未选定节点");
                return;
            }

            BerNode bernode = (BerNode)node.Tag;

            if (TreeNodeLevel(node) != 1)
            {
                MessageBox.Show(this, "必须是Ber包根节点");
                return;
            }

            BerNode root         = bernode;
            int     nRet         = 0;
            string  strError     = "";
            string  strDebugInfo = "OK";

            if (root.m_uTag == BerTree.z3950_initRequest)
            {
                // 观察Initial请求包
                nRet = BerTree.GetInfo_InitRequest(
                    root,
                    out strDebugInfo,
                    out strError);
            }
            else if (root.m_uTag == BerTree.z3950_searchRequest)
            {
                nRet = BerTree.GetInfo_SearchRequest(
                    root,
                    out strDebugInfo,
                    out strError);
            }
            else if (root.m_uTag == BerTree.z3950_presentRequest)
            {
                nRet = BerTree.GetInfo_PresentRequest(
                    root,
                    out strDebugInfo,
                    out strError);
            }
            else if (root.m_uTag == BerTree.z3950_initResponse)
            {
                nRet = BerTree.GetInfo_InitResponse(root,
                                                    out strDebugInfo,
                                                    out strError);
            }
            else if (root.m_uTag == BerTree.z3950_searchResponse)
            {
                nRet = BerTree.GetInfo_SearchResponse(root,
                                                      out strDebugInfo,
                                                      out strError);
            }
            else if (root.m_uTag == BerTree.z3950_presentResponse)
            {
                RecordCollection records         = null;
                SEARCH_RESPONSE  search_response = new SEARCH_RESPONSE();
                nRet = BerTree.GetInfo_PresentResponse(root,
                                                       ref search_response,
                                                       out records,
                                                       true,
                                                       out strError);
            }

            if (nRet == -1)
            {
                MessageBox.Show(this, strError);
            }
            else
            {
                MessageBox.Show(this, strDebugInfo);
            }
        }
示例#28
0
文件: Session.cs 项目: renyh1013/dp2
        // 编码(构造) Search响应包
        int Encode_SearchResponse(SearchRequestInfo info,
            out byte[] baPackage,
            out string strError)
        {
            baPackage = null;
            int nRet = 0;
            long lRet = 0;
            strError = "";

            DiagFormat diag = null;

            BerTree tree = new BerTree();
            BerNode root = null;

            long lSearchStatus = 0; // 0 失败;1成功
            long lHitCount = 0;

            string strQueryXml = "";
            // 根据逆波兰表进行检索

            // return:
            //      -1  error
            //      0   succeed
            nRet = BuildQueryXml(
                info.m_dbnames,
                info.m_rpnRoot,
                out strQueryXml,
                out strError);
            if (nRet == -1)
            {
                SetPresentDiagRecord(ref diag,
                    2,  // temporary system error
                    strError);
            }

            string strResultSetName = info.m_strResultSetName;
            if (String.IsNullOrEmpty(strResultSetName) == true)
                strResultSetName = "default";

            if (diag == null)
            {
                lRet = _channel.Search(null,
                    strQueryXml,
                    strResultSetName,
                    "", // strOutputStyle
                    out strError);

                /*
                // 测试检索失败
                lRet = -1;
                strError = "测试检索失败";
                 * */

                if (lRet == -1)
                {
                    lSearchStatus = 0;  // failed

                    SetPresentDiagRecord(ref diag,
                        2,  // temporary system error
                        strError);
                }
                else
                {
                    lHitCount = lRet;
                    lSearchStatus = 1;  // succeed
                }
            }


            root = tree.m_RootNode.NewChildConstructedNode(
                BerTree.z3950_searchResponse,
                BerNode.ASN1_CONTEXT);

            // reference id
            if (String.IsNullOrEmpty(info.m_strReferenceId) == false)
            {
                root.NewChildCharNode(BerTree.z3950_ReferenceId,
                    BerNode.ASN1_CONTEXT,
                    Encoding.UTF8.GetBytes(info.m_strReferenceId));
            }


            // resultCount
            root.NewChildIntegerNode(BerTree.z3950_resultCount, // 23
                BerNode.ASN1_CONTEXT,   // ASNI_PRIMITIVE BUG!!!!
                BitConverter.GetBytes((long)lHitCount));

            // numberOfRecordsReturned
            root.NewChildIntegerNode(BerTree.z3950_NumberOfRecordsReturned, // 24
                BerNode.ASN1_CONTEXT,   // ASNI_PRIMITIVE BUG!!!!
                BitConverter.GetBytes((long)0/*info.m_lNumberOfRecordReturned*/));    // 0

            // nextResultSetPosition
            root.NewChildIntegerNode(BerTree.z3950_NextResultSetPosition, // 25
                BerNode.ASN1_CONTEXT,   // ASNI_PRIMITIVE BUG!!!!
                BitConverter.GetBytes((long)1/*info.m_lNextResultSetPosition*/));

            // 2007/11/7 原来本项位置不对,现在移动到这里
            // bool
            // searchStatus
            root.NewChildIntegerNode(BerTree.z3950_searchStatus, // 22
                BerNode.ASN1_CONTEXT,   // ASNI_PRIMITIVE BUG!!!!
                BitConverter.GetBytes((long)lSearchStatus));

            // resultSetStatus OPTIONAL

            // 2007/11/7
            // presentStatus
            root.NewChildIntegerNode(BerTree.z3950_presentStatus, // 27
                BerNode.ASN1_CONTEXT,   // ASNI_PRIMITIVE BUG!!!!
                BitConverter.GetBytes((long)0));


            // 诊断记录
            if (diag != null)
            {
                BerNode nodeDiagRoot = root.NewChildConstructedNode(BerTree.z3950_nonSurrogateDiagnostic,    // 130
                    BerNode.ASN1_CONTEXT);

                diag.BuildBer(nodeDiagRoot);
            }

            baPackage = null;
            root.EncodeBERPackage(ref baPackage);

            return 0;
        }
示例#29
0
        // 获得记录
        // 本函数每次调用前,最好调用一次 TryInitialize()
        // 不确保一定可以获得nCount个
        // parameters:
        //		nStart	获取记录的开始位置(从0开始计数)
        public async Task <PresentResult> OncePresent(
            string strResultSetName,
            int nStart,
            int nCount,
            string strElementSetName,
            string strPreferredRecordSyntax)
        {
            if (nCount == 0)
            {
                return new PresentResult {
                           Value = 0, ErrorInfo = "nCount 参数为 0,本次没有真正请求服务器获取记录"
                }
            }
            ;

            BerTree         tree = new BerTree();
            PRESENT_REQUEST struPresent_request = new PRESENT_REQUEST();

            //byte[] baPackage = null;
            //int nRet;

            struPresent_request.m_strReferenceId            = this._currentRefID;
            struPresent_request.m_strResultSetName          = strResultSetName; // "default";
            struPresent_request.m_lResultSetStartPoint      = nStart + 1;
            struPresent_request.m_lNumberOfRecordsRequested = nCount;
            struPresent_request.m_strElementSetNames        = strElementSetName;
            struPresent_request.m_strPreferredRecordSyntax  = strPreferredRecordSyntax;

            int nRet = tree.PresentRequest(struPresent_request,
                                           out byte[] baPackage);

            if (nRet == -1)
            {
                return new PresentResult {
                           Value = -1, ErrorInfo = "CBERTree::PresentRequest() fail!"
                }
            }
            ;
            if (this._channel.Connected == false)
            {
                this.CloseConnection();

                return(new PresentResult {
                    Value = -1, ErrorInfo = "socket尚未连接或者已经被关闭"
                });
            }

#if DUMPTOFILE
            DeleteFile("presentrequest.bin");
            DumpPackage("presentrequest.bin",
                        (char *)baPackage.GetData(),
                        baPackage.GetSize());
            DeleteFile("presentrequest.txt");
            tree.m_RootNode.DumpToFile("presentrequest.txt");
#endif

            BerTree tree1 = new BerTree();

            {
                RecvResult result = await this._channel.SendAndRecv(
                    baPackage);

                if (result.Value == -1)
                {
                    return(new PresentResult(result));
                }

#if DUMPTOFILE
                DeleteFile("presendresponse.bin");
                DumpPackage("presentresponse.bin",
                            (char *)baPackage.GetData(),
                            baPackage.GetSize());
#endif


                tree1.m_RootNode.BuildPartTree(result.Package,
                                               0,
                                               result.Package.Length,
                                               out int nTotalLen);
            }

#if DUMPTOFILE
            DeleteFile("PresentResponse.txt");
            tree1.m_RootNode.DumpDebugInfoToFile("PresentResponse.txt");
#endif
            SEARCH_RESPONSE search_response = new SEARCH_RESPONSE();
            nRet = BerTree.GetInfo_PresentResponse(tree1.GetAPDuRoot(),
                                                   ref search_response,
                                                   out RecordCollection records,
                                                   true,
                                                   out string strError);
            if (nRet == -1)
            {
                return new PresentResult {
                           Value = -1, ErrorInfo = strError
                }
            }
            ;

            SetElementSetName(records, strElementSetName);

            if (search_response.m_diagRecords.Count != 0)
            {
                return new PresentResult {
                           Value = -1, ErrorInfo = "error diagRecords:\r\n\r\n---\r\n" + search_response.m_diagRecords.GetMessage()
                }
            }
            ;

            return(new PresentResult {
                Records = records
            });
        }
示例#30
0
        // 发出超大攻击请求包
        // return:
        //      -1  出错
        //      0   正确发出
        //      1   发出前,发现流中有未读入的数据
        public static async Task <Result> SendInfinitPackage(
            TcpClient _client,
            int length)
        {
            Result result = new Result();

            if (_client == null)
            {
                result.Value     = -1;
                result.ErrorInfo = "client尚未初始化。请重新连接和检索。";
                return(result);
            }

            if (_client == null)
            {
                result.Value     = -1;
                result.ErrorInfo = "用户中断";
                return(result);
            }

            NetworkStream stream = _client.GetStream();

            if (stream.DataAvailable == true)
            {
                result.Value     = 1;
                result.ErrorInfo = "发送前发现流中有未读的数据";
                return(result);
            }

            try
            {
                {
                    BerTree tree = new BerTree();

                    BerNode root = tree.m_RootNode.NewChildConstructedNode(BerTree.z3950_initRequest,
                                                                           BerNode.ASN1_CONTEXT);

                    byte[] baTempPackage = null;

                    root.MakeHeadPart(ref baTempPackage, length);
                    await stream.WriteAsync(baTempPackage, 0, baTempPackage.Length).ConfigureAwait(false);
                }

#if NO
                for (int i = 0; i < length; i++)
                {
                    byte[] baPackage = new byte[1];

                    await stream.WriteAsync(baPackage, 0, 1).ConfigureAwait(false);
                }
#endif
                int chunk_size = 4096 * 10;
                for (int i = 0; i < (length / chunk_size) + 1; i++)
                {
                    byte[] baPackage = new byte[chunk_size];

                    await stream.WriteAsync(baPackage, 0, chunk_size).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                if (ex is IOException && ex.InnerException is SocketException)
                {
                    // "ConnectionAborted"
                    result.ErrorCode = ((SocketException)ex.InnerException).SocketErrorCode.ToString();
                }

                result.Value     = -1;
                result.ErrorInfo = "send出错: " + ex.Message;
                return(result);
            }

            return(result);
        }