希望对 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();
}
}
}
}
错误出在传入数据上,它要么是配置为以不同方式发送数据的 GPS 设备,要么是一些随机 tcp 事件。检查您在Google搜索中使用的端口号,并确保它不是为其他内容保留的。
这段代码肯定不会处理那么多连接,你遍历一个字节数组并一次转换一个字符(改用System.Text.Encoding.ASCII.GetString(byte[]),你在接收块中打开和关闭与sql服务器的连接等等。为了处理此类活动,您只需读取数据并将其放入总线或临时存储中进行批量处理。
您假设一次将阅读一条消息。TCP 提供无边界的字节流。您可以很好地阅读部分消息或多条消息。
如何处理这取决于流的格式。如果它是基于线的StreamReader.ReadLine()
是一个很好的解决方案。