简体   繁体   English

同时进行Oracle连接和TCP客户端/服务器连接

[英]Oracle Connection and TCP Client/Server Connection at same time

I am writing a program that will live on a "Super PC" in my lab at work. 我正在编写一个程序,该程序将在我的实验室的“超级PC”上运行。 Its job is to constantly query our customers databases proactively looking for common errors that we encounter. 它的工作是不断查询客户数据库,以主动查找我们遇到的常见错误。

It accomplishes this by using an adjustable timer and simply running down the list of queries and databases and interpreting the results.(Queries and Database connections are added using a Configuration UI) 它通过使用可调计时器并简单地运行查询和数据库列表并解释结果来实现此目的(使用配置UI添加查询和数据库连接)。

This program has a TCP client/server connection with another app that I have written that lives on my team members personal machines. 该程序与我编写的另一个应用程序建立了TCP客户端/服务器连接,该应用程序位于团队成员的个人计算机上。 Messages get sent from the Server(Query) program to the client program alerting my team of errors found in the Databases. 消息从Server(Query)程序发送到客户端程序,提醒我的团队发现数据库中的错误。

The problem I keep encountering is occasionally a message gets sent through the socket at the exact same time a DB connection is made or a query is run and it causes the server program to crash with no explanation. 我一直遇到的问题是,偶尔在建立数据库连接或运行查询的同时,通过套接字发送一条消息,这导致服务器程序崩溃,没有任何解释。

The methods that run the queries is always called in its own thread as well as the server connection is made in its own thread. 运行查询的方法总是在其自己的线程中调用,而服务器连接则在其自己的线程中建立。

In addition I have placed all of the DB methods and Client Server methods in Try/Catch blocks that are setup to catch all exceptions and display the stack trace, but for some reason when it crashes its not hitting any of the catch. 另外,我将所有DB方法和Client Server方法放在Try / Catch块中,它们被设置为捕获所有异常并显示堆栈跟踪,但是由于某种原因,当它崩溃时,它没有命中任何捕获。

The runQueries Methods is called off a C# .Net System.Timers.Timer which is supposed to launch a new thread on every tick. C#.Net System.Timers.Timer调用了runQueries方法,该方法应该在每个刻度上启动一个新线程。

Below are my Client/Server Methods and Query Methods 以下是我的客户端/服务器方法和查询方法

    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;



    }

Query timer initialization 查询计时器初始化

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

Tick method for query timer 查询计时器的刻度方法

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

How the server thread is started 服务器线程如何启动

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

Does anyone have any idea why this might be happening? 有谁知道为什么会这样? Both programs work as described and do what they are supposed to its just when more and more clients begin connecting to the server it becomes more and more likely that a TCP connection and DB connection will occur at the same time. 当越来越多的客户端开始连接到服务器时,这两个程序都按照描述的方式工作,并按照其预期的方式工作,TCP连接和DB连接同时发生的可能性越来越大。

Update 12:20 9/15/14 更新12:20 9/15/14

So I'm trying to upload a pic of the log from the last crash... but i don't have enough rep points... derp, anyway 所以我正试图上传上次崩溃的日志图片...但是我没有足够的代表点...反正

This time the last line in the log is from a log purge(deletes log entries older than 24 hours) 这次,日志中的最后一行来自日志清除(删除早于24小时的日志条目)

However the program will only crash when I have the client program set to auto refresh. 但是,只有当我将客户端程序设置为自动刷新时,程序才会崩溃。 IE Client app has a button to request messages from server or user can select auto-refresh which sets request function to timer. IE客户端应用程序具有一个从服务器请求消息的按钮,或者用户可以选择自动刷新,从而将请求功能设置为计时器。

My only other thought is that multiple threads are trying to write to the log file at the same time, however my write to log method uses writeLinesAsync() so that shouldn't be a problem? 我唯一的另一种想法是,多个线程试图同时写入日志文件,但是我的log方法使用writeLinesAsync(),所以应该不会有问题吗?

This issue turned out to be caused by multiple threads trying to write to the log file at the same time. 原来,此问题是由多个线程试图同时写入日志文件引起的。

I resolved it by following @user469104's advice and creating an internal lock object to lock the writeToLog methods. 我通过遵循@ user469104的建议并创建一个内部锁定对象来锁定writeToLog方法来解决此问题。

Both client and server apps have been running for multiple days now without breaking. 客户端和服务器应用程序已经运行了好几天,而且没有中断。

Thanks Everyone! 感谢大家!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM