同时使用Oracle连接和TCP客户端/服务器连接

本文关键字:连接 TCP 客户端 服务器 Oracle | 更新日期: 2023-09-27 18:22:05

我正在写一个程序,该程序将在我实验室的"超级PC"上运行。它的工作是不断主动地查询我们的客户数据库,寻找我们遇到的常见错误。

它通过使用一个可调整的定时器,简单地运行查询和数据库列表并解释结果来实现这一点。(使用配置UI添加查询和数据库连接)

这个程序与我编写的另一个应用程序有TCP客户端/服务器连接,该应用程序位于我的团队成员的个人计算机上。消息从服务器(查询)程序发送到客户端程序,提醒我的团队在数据库中发现错误。

我一直遇到的问题是,偶尔会在建立数据库连接或运行查询的同时,通过套接字发送一条消息,这会导致服务器程序崩溃,而没有任何解释。

运行查询的方法总是在其自己的线程中调用,服务器连接也是在其自己线程中进行的。

此外,我将所有DB方法和Client-Server方法都放在Try/Catch块中,这些块被设置为捕获所有异常并显示堆栈跟踪,但由于某种原因,当它崩溃时,它没有命中任何Catch。

runQueries方法是从一个C#.Net System.Timers.Timer调用的,它应该在每个刻度上启动一个新线程。

以下是我的客户端/服务器方法和查询方法

    private void serverMeth()
    {
        try
        {
            /*conbox.Text = conbox.Text + "The server is running at port 8001..." + Environment.NewLine;
            conbox.Text = conbox.Text + "The local End point is  :" + myList.LocalEndpoint + Environment.NewLine;
            conbox.Text = conbox.Text + "Waiting for a connection....." + Environment.NewLine;*/
            msglist.Add("The server is running at port 8001...");
            msglist.Add("The local end point is: " + myList.LocalEndpoint);
            msglist.Add("Waiting for a connection...");
            writeToLog("Listening for connection at "+myList.LocalEndpoint);
            /* Start Listeneting at the specified port */
            while (true)
            {
                gatherErrors();
                myList.Start();
                //Socket s = myList.AcceptSocket();
                s = myList.AcceptSocket();
                //conbox.Text = conbox.Text + "Connection accepted from " + s.RemoteEndPoint + Environment.NewLine;
                msglist.Add("Connection accepted from " + s.RemoteEndPoint);
                writeToLog("Connection Established @" + myList.LocalEndpoint);
                byte[] b = new byte[20000];
                int k = s.Receive(b);
                    //conbox.Text = conbox.Text + "Recieved..." + Environment.NewLine;
                    msglist.Add("Recieved...");
                writeToLog("Message Recieved from Command Center");
                //for (int i = 0; i < k; i++)
                //{ conbox.Text = conbox.Text + Convert.ToChar(b[i]); }
                string message = ""; //allows it to store the entire message in one line
                string dt = DateTime.Now.ToString("MM-dd-yyyy hh:mm:ss");
                string eid = "TEST ID";
                for (int i = 0; i < k; i++)
                { message = message + Convert.ToChar(b[i]); }
                if (message.Contains(uniquekey))
                {
                    writeToLog("Message contains correct passcode");
                    message = message.Replace(uniquekey, "");
                    String[] splits = message.Split(',');
                    message = message.Replace("," + splits[1], "");
                    writeToLog("Connection from " + splits[1]);
                    msglist.Add(message); //this takes the completed message and adds it.
                    //DO IGNORE STUF HERE
                    if (!message.Equals(""))
                    {
                        //Message contains error key
                        Error erro = null;
                        for (int i = 0; i < errorss.Count; i++)
                        {
                            if (errorss[i].getKey().Equals(message)) {
                                erro = errorss[i];
                            }
                        }
                        Stage st = null;
                        if (erro != null)
                        {
                            for (int i = 0; i < stages.Count; i++)
                            {
                                if (stages[i].errContainCheck(erro))
                                {
                                    st = stages[i];
                                }
                            }
                        }
                        if (st != null)
                        {
                            st.addIgnore(erro);
                            writeToLog("Error: " + erro.getKey() + "ignored");
                        }
                    }
                    //conbox.Text = conbox.Text + Environment.NewLine;
                    msglist.Add(" ");
                    string msg = "";
                    string log = "Error(s): ";
                    for (int i = 0; i < errorss.Count; i++)
                    {
                        msg += errorss[i].getTime() + "|"+errorss[i].getMsg()+"|" + errorss[i].getSite()+"|"+errorss[i].getKey();
                        msg += ",";
                        log += errorss[i].getKey()+",";
                    }
                    log+= "sent to Command Center";
                        ASCIIEncoding asen = new ASCIIEncoding();
                        s.Send(asen.GetBytes(msg));
                        //conbox.Text = conbox.Text + "'nSent Acknowledgement" + Environment.NewLine;
                        msglist.Add("'nSent Acknowledgement");
                    writeToLog(log);
                }
                else
                {
                    message = "Unauthorized access detected. Disregarding message.";
                    //.Add(message); //this takes the completed message and adds it.
                    //conbox.Text = conbox.Text + Environment.NewLine;
                    msglist.Add(" ");
                    writeToLog("Passcode mismatch");
                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes("Access Denied.  Unique key mismatch."));
                    //conbox.Text = conbox.Text + "'nSent Acknowledgement" + Environment.NewLine;
                    msglist.Add("'nSent Denial Acknowledgement");
                }

                /* clean up */
                s.Close();
                myList.Stop();
                if (quit == true)
                {
                    break;
                }
            }
        }
        catch (Exception err)
        {
            //conbox.Text = conbox.Text + "Error..... " + err.StackTrace + Environment.NewLine;
            msglist.Add("Error..... " + err.StackTrace);
            writeToLog("ERROR: "+err.StackTrace);
        }
    }
    private void sasDownload()
    {
        int selItemList;
        selItemList = saerrlist.SelectedIndex;
        saerrlist.Items.Clear();  //clears the list before redownload
        saerrgrid.Rows.Clear();
        try
        {
            TcpClient tcpclnt = new TcpClient();
            //clibox.Text = clibox.Text + "Connecting....." + Environment.NewLine;
            tcpclnt.Connect(staralertip.Text, 8001);
            // use the ipaddress as in the server program
            //clibox.Text = clibox.Text + "Connected" + Environment.NewLine;
            //clibox.Text = clibox.Text + "Enter the string to be transmitted : " + Environment.NewLine;

            String str = "982jsdf293jsadd02jkdas20dka2";
            Stream stm = tcpclnt.GetStream();
            if (ackClick)
            {
                str += ackKey;
                ackClick = false;
            }
            String name = "User not found";
            for (int i = 0; i < users.Count(); i++)
            {
                if(users[i].sys_id.Equals(SNLists.loggedinuser)){
                    name = users[i].name;
                    break;
                }
            }
            str += "," + name;
            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] ba = asen.GetBytes(str);
            //clibox.Text = clibox.Text + "Transmitting....." + Environment.NewLine;
            stm.Write(ba, 0, ba.Length);
            byte[] bb = new byte[20000];
            int k = stm.Read(bb, 0, 20000);
            string incmsg = "";
            for (int i = 0; i < k; i++)
                incmsg = incmsg + Convert.ToChar(bb[i]);

            string tempmsg = "";
            foreach (char c in incmsg)
            {
                if (c != ',')
                {
                    tempmsg = tempmsg + c;
                }
                else if (c == ',')
                {
                    saerrlist.Items.Add(tempmsg);
                    saerrgrid.Rows.Add(tempmsg.Split('|')[0], tempmsg.Split('|')[1], tempmsg.Split('|')[2], tempmsg.Split('|')[3]);
                    tempmsg = "";
                }
            }
            saerrlist.Items.Add(tempmsg);
            //saerrgrid.Rows.Add(tempmsg.Split('|')[0], tempmsg.Split('|')[1], tempmsg.Split('|')[2]);

            //MessageBox.Show(incmsg);
            tcpclnt.Close();
        }
        catch (Exception err)
        {
            //MessageBox.Show("Error..... " + err.StackTrace, "STAR Command Center: Connectivity Error");
            staralertTimer.Enabled = false;
            MessageBox.Show("Error downloading recent errors from STAR Alert System.'n'nPlease confirm STAR Alert is running " +
                            "and hit '"Refresh'" in the STAR Alert tab." + "'n" + err, "STAR Command Center: Connectivity Error");
        }
        saerrlist.SelectedIndex = selItemList;
    }

    public void runQueries()
    {
        OracleConnection con = new OracleConnection();
        int siteNum = -1;
        try
        {
            writeToLog("Call to runQueries");
            List<List<Error>> results = new List<List<Error>>();
            for (int i = 0; i < ppreset.getSites().Count(); i++)
            {
                siteNum = i;
                Site s = ppreset.getSites()[i];
                if (s.getStatus().Equals("ACTIVE"))
                {
                    //OracleConnection con = new OracleConnection();
                    String it = "User Id=" + s.getLogin() + ";Password=" + s.getPassword() + ";Data Source=" + s.getDbName();
                    con.ConnectionString = it;
                    //con.OpenAsync();
                    con.Open();
                    writeToLog("Connection opened for site: " + s.getSite());
                    List<Error> subResults = new List<Error>();
                    for (int j = 0; j < s.getQueries().Count(); j++)
                    {
                        Query q = s.getQueries()[j];
                        string sql = q.getCode();
                        List<string> columns = getColumns(sql);
                        List<List<String>> mast = new List<List<String>>();
                        for (int m = 0; m < columns.Count(); m++)
                        {
                            mast.Add(new List<String>());
                        }
                        OracleCommand cmd = new OracleCommand(sql, con);
                        cmd.CommandType = CommandType.Text;
                        OracleDataReader dr = cmd.ExecuteReader();
                        writeToLog("Execute SQL, Begin Reading results...");
                        // dr.Read();
                        //List<String> results = new List<String>();
                        if (dr.HasRows)
                        {
                            //MessageBox.Show("has rows");
                            while (dr.Read())
                            {
                                //string result = "";
                                for (int p = 0; p < columns.Count(); p++)
                                {
                                    if (columns.Count() != 0)
                                    {
                                        mast[p].Add(dr[columns[p]].ToString());
                                    }
                                }
                                //results.Add(result);

                            }
                        }

                        subResults.AddRange(ruleCheck(mast, q.getRules(), s.getQueries()[j], ppreset.getSites()[i].getSite()));
                        cmd.Dispose();
                        writeToLog("Done reading");

                    }
                    results.Add(subResults);
                    // con.Dispose();
                    con.Close();
                    writeToLog("Connection Closed for site: " + s.getSite());
                }
            }
            //we now have all of the error strings gathered from running all queries on all sites in the given preset
            //lets send them to a method that will change the status' of the modules and makem RAVVEEEEE
            //update(results);

            if (errors == null && results.Count != 0)
            {
                //MessageBox.Show("errors = results");
                errors = results;
                writeToLog("First error found...errors = results");
                for (int i = 0; i < results.Count; i++)
                {
                    for (int j = 0; j < results[i].Count; j++)
                    {
                        if (foncig.lallerdisc == true)
                        {
                            sendLyncMsg(results[i][j].getMsg());
                            writeToLog("Lync Msg sent");
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < results.Count; i++)
                {
                    for (int j = 0; j < results[i].Count; j++)
                    {
                        errors[i].Add(results[i][j]);
                        writeToLog("Error: " + results[i][j].getKey() + " added");
                        // MessageBox.Show("Error added to errors");
                        //////////////////////////////////////////////////////////////////////////////
                        ////////////////////////////////////////////////////////////////////////////////
                        //LYNC STUFF CAN GO HERE///////////////////////////////////////////////////////
                        ///////////////////////////////////////////////////////////////////////////////
                        /////FOR EACH ERROR ADDED TO MASTER LIST SEND LYNC///////////////////////////
                        //////////////////////////////////////////////////////////////////////////////
                        if (foncig.lallerdisc == true)
                        {
                            sendLyncMsg(results[i][j].getMsg());
                            writeToLog("Lync msg sent");
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {//MessageBox.Show("Err: " + e);
            badConn[siteNum] += "x";
            writeToLog("Connection error strike added to " + ppreset.getSites()[siteNum].getSite());
            con.Close();
            checkForBadConn();
            writeToLog( e.StackTrace);
        }
        //foncig.errors = errors;
        //here we will check all of the errors in results against all of the errors  in errors
        //if the error is not in errors add it
        //errors = results;

    }

查询计时器初始化

    queryTimer = new System.Timers.Timer(120000);
        queryTimer.Elapsed += queryTimer_Tick;
        queryTimer.Enabled = true;

查询计时器的勾选方法

    private void queryTimer_Tick(object sender, EventArgs e)
    {
        GC.Collect();
        try
        {
            runQueries();
        }
        catch (OracleException err)
        {
           // MessageBox.Show("Err: " + err);
        }
    }

如何启动服务器线程

    server = new Thread(serverMeth);
        server.Start();

有人知道为什么会发生这种事吗?这两个程序都按照描述工作,并按照预期进行操作。就在越来越多的客户端开始连接到服务器时,TCP连接和DB连接同时发生的可能性越来越大。

更新时间:2014年9月15日12:20

所以我试图上传一张上次崩溃日志的照片。。。但我没有足够的代表点。。。derp,无论如何

这一次,日志中的最后一行来自日志清除(删除超过24小时的日志条目)

然而,只有当我将客户端程序设置为自动刷新时,该程序才会崩溃。IE客户端应用程序有一个按钮,可以从服务器请求消息,或者用户可以选择自动刷新,将请求功能设置为计时器。

我唯一的另一个想法是多个线程试图同时写入日志文件,但是我的写入日志方法使用了writeLinesAsync(),所以这应该不是问题吗?

同时使用Oracle连接和TCP客户端/服务器连接

这个问题是由多个线程试图同时写入日志文件引起的。

我按照@user469104的建议解决了这个问题,并创建了一个内部锁定对象来锁定writeToLog方法。

客户端和服务器应用程序已经运行了好几天,没有中断。

谢谢大家!