希望对 SQL Server 数据库应用程序的 C# TCP 侦听器进行代码改进

本文关键字:侦听器 TCP 代码 SQL Server 数据库 应用程序 希望 | 更新日期: 2023-09-27 17:55:37

我构建了一个 C# 控制台应用程序,它接受来自我拥有的 GPS 报告设备的 TCP 连接。我构建了这个应用程序来收集该数据并将其转储到 SQL Server 表中。

目前,我

让应用程序正常工作,但它有一个我似乎无法弄清楚的错误。当 GPS 设备建立连接时,随机的 1-10 个成功连接中的一个给了我一个超出范围的索引异常。

当我转储原始数据时,它看起来不像设备发送给我的东西。你们中有人碰巧知道是什么原因造成的吗?另外,一旦我让这个应用程序正常工作,它每分钟最多可以接收 3-5k 个连接,你认为这段代码可以处理这个问题吗?

这是我经常收到的错误,转储杂项数据:

错误图像

这是我的代码:

namespace GPS2DB
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                IPAddress ipAddress = IPAddress.Parse("10.71.150.253");
                Console.WriteLine("Waiting for Tracker Connections...");
                TcpListener listener = new TcpListener(ipAddress, 10000);
                listener.Start();
                while (true)
                {
                    Socket client = listener.AcceptSocket();
                    Console.WriteLine("Connection accepted.");
                    var childSocketThread = new Thread(() =>
                    {
                        byte[] data = new byte[1024];
                        int size = client.Receive(data);
                        string gpsData = "";
                        for (int i = 0; i < size; i++)
                        {
                            Console.Write(Convert.ToChar(data[i]));
                            gpsData = gpsData + Convert.ToChar(data[i]);
                        }
                        string txt = gpsData;
                        string txt2 = (txt.Trim(new Char[] { '$', '#' }));
                        String[] values = txt2.Split(',');
                        //Console.WriteLine(txt2);
                        /*
                        Console.WriteLine("Unit ID: " + values[0]);
                        Console.WriteLine("Event Code: " + values[1]);
                        Console.WriteLine("UTC Date: " + values[2]);
                        Console.WriteLine("UTC Time: " + values[3]);
                        Console.WriteLine("Lat: " + values[4]);
                        Console.WriteLine("Long: " + values[5]);
                        Console.WriteLine("Speed: " + values[7]);
                        Console.WriteLine("Heading: " + values[11]);
                        Console.WriteLine("V+: " + values[16]);
                        Console.WriteLine("Cell Strength: " + values[17]);
                        Console.WriteLine("GPS Status: " + values[18]);
                        Console.WriteLine("Fuel Level: " + values[20]);
                        */
                        //dump 2 database
                        string connectionString = "Data Source=DVT501;Initial Catalog=VehicleTracking;Persist Security Info=True;User ID=TABLE;Password=PASS";
                        using (SqlConnection connection = new SqlConnection(connectionString))
                        {
                            SqlCommand cmd = new SqlCommand("INSERT INTO Data_Dump (uid, eventCode, utcDate, utcTime, lat, long, speed, heading, voltage, cellStrength, gpsStatus, fuelLevel) VALUES (@uid, @eventCode, @utcDate, @utcTime, @lat, @long, @speed, @heading, @voltage, @cellStrength, @gpsStatus, @fuelLevel)");
                            cmd.CommandType = System.Data.CommandType.Text;
                            cmd.Connection = connection;
                            try
                            { 
                            cmd.Parameters.AddWithValue("@uid", values[0]);
                            cmd.Parameters.AddWithValue("@eventCode", values[1]);
                            cmd.Parameters.AddWithValue("@utcDate", values[2]);
                            cmd.Parameters.AddWithValue("@utcTime", values[3]);
                            cmd.Parameters.AddWithValue("@lat", values[4]);
                            cmd.Parameters.AddWithValue("@long", values[5]);
                            cmd.Parameters.AddWithValue("@speed", values[7]);
                            cmd.Parameters.AddWithValue("@heading", values[11]);
                            cmd.Parameters.AddWithValue("@voltage", values[16]);
                            cmd.Parameters.AddWithValue("@cellStrength", values[17]);
                            cmd.Parameters.AddWithValue("@gpsStatus", values[18]);
                            cmd.Parameters.AddWithValue("@fuelLevel", values[20]);
                            connection.Open();
                            cmd.ExecuteNonQuery();
                        }
                        catch (System.IndexOutOfRangeException e)
                        {
                            Console.WriteLine("IndexOutOfRangeException caught" + e);
                            Console.WriteLine(txt);
                        }
                    }
                    //end dump
                    Console.WriteLine();
                    client.Close();
                });
                childSocketThread.Start();
             }
             listener.Stop();
          }               
          catch (Exception e)
          {
                Console.WriteLine("Error: " + e.StackTrace);
                Console.ReadLine();
          }
        }
    }
}

希望对 SQL Server 数据库应用程序的 C# TCP 侦听器进行代码改进

错误出在传入数据上,它要么是配置为以不同方式发送数据的 GPS 设备,要么是一些随机 tcp 事件。检查您在Google搜索中使用的端口号,并确保它不是为其他内容保留的。

这段代码肯定不会处理那么多连接,你遍历一个字节数组并一次转换一个字符(改用System.Text.Encoding.ASCII.GetString(byte[]),你在接收块中打开和关闭与sql服务器的连接等等。为了处理此类活动,您只需读取数据并将其放入总线或临时存储中进行批量处理。

您假设一次将阅读一条消息。TCP 提供无边界的字节流。您可以很好地阅读部分消息或多条消息。

如何处理这取决于流的格式。如果它是基于线的StreamReader.ReadLine()是一个很好的解决方案。