gpt4 book ai didi

c# - 具有线程性能的 tcp 监听器

转载 作者:可可西里 更新时间:2023-11-01 02:53:53 31 4
gpt4 key购买 nike

我正在构建 GPS 应用程序,其中 GPS 设备通过 tcp 端口发送位置我正在构建一项服务来读取这些消息并将其保存到数据库

    static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(8889);
TcpClient clientSocket = default(TcpClient);
int counter = 0;

serverSocket.Start();
// Console.WriteLine(" >> " + "Server Started");

counter = 0;
while (true)
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
// Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!");
handleClinet client = new handleClinet();
client.startClient(clientSocket, Convert.ToString(counter));
}

clientSocket.Close();
serverSocket.Stop();
// Console.WriteLine(" >> " + "exit");
Console.ReadLine();
}
}

//Class to handle each client request separatly
public class handleClinet
{

static void WriteLog(string message, EventLogEntryType type)
{

using (EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "Application";
eventLog.WriteEntry(message, type, 101, 1);
}
}
static int InsideDangerArea(double Lat, double Lng)
{

string point = "POINT(" + Lng + " " + Lat + ")";

string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";
using (SqlConnection conn = new SqlConnection(ConnStr))
{
conn.Open();
using (SqlCommand comm = new SqlCommand("Select id from T_Geofncies", conn))
{
DataTable dt = new DataTable();
dt.Load(comm.ExecuteReader());

foreach (DataRow dr in dt.Rows)
{
string Query = " DECLARE @g geometry; DECLARE @h geometry; SET @g = (select(points) from T_Geofncies where id=" + dr["id"].ToString() + " );";
Query += " SET @h = geometry::STGeomFromText('" + point + "', 4326); SELECT @g.STContains(@h);";
comm.CommandText = Query;
int Val = Convert.ToInt32(comm.ExecuteScalar());
if (Val == 1)
{
conn.Close();
conn.Dispose();
return Convert.ToInt32(dr["id"]);
}

}
}
conn.Close();
conn.Dispose();
}
return 0;
}

static int OutsideSafeArea(double Lat, double Lng)
{

string point = "POINT(" + Lng + " " + Lat + ")";

string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";
using (SqlConnection conn = new SqlConnection(ConnStr))
{
conn.Open();
using (SqlCommand comm = new SqlCommand("Select id from T_SafeArea", conn))
{
DataTable dt = new DataTable();
dt.Load(comm.ExecuteReader());

foreach (DataRow dr in dt.Rows)
{
string Query = " DECLARE @g geometry; DECLARE @h geometry; SET @g = (select(points) from T_SafeArea where id=" + dr["id"].ToString() + " );";
Query += " SET @h = geometry::STGeomFromText('" + point + "', 4326); SELECT @g.STContains(@h);";
comm.CommandText = Query;
int Val = Convert.ToInt32(comm.ExecuteScalar());
if (Val == 1)
{
conn.Close();
conn.Dispose();
return Convert.ToInt32(dr["id"]);
}

}
}
conn.Close();
conn.Dispose();
}
return 0;
}
static SqlGeography GetGeographyFromText(String pText)
{
SqlString ss = new SqlString(pText);
SqlChars sc = new SqlChars(ss);
try
{
return SqlGeography.STPointFromText(sc, 4326);
}
catch (Exception ex)
{
throw ex;
}
}
TcpClient clientSocket;
string clNo;
public void startClient(TcpClient inClientSocket, string clineNo)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";

int requestCount = 0;
// byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;

while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
int i;
int size = (int)clientSocket.ReceiveBufferSize;
// Loop to receive all the data sent by the client.
Byte[] bytes = new Byte[size];
string data = "";
string IMEI;
while ((i = networkStream.Read(bytes, 0, bytes.Length)) != 0)
{

try
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

string[] tokens = data.Split(new[] { "GPRMC" }, StringSplitOptions.None);
var longest = Regex.Matches(data, @"\d+").Cast<Match>().OrderByDescending(m => m.Length).First();


IMEI = longest.ToString();
if (IMEI.Length > 15)
IMEI = IMEI.Substring(1);



foreach (string item in tokens)
{
try
{
string[] Values = item.Split(','); // Console.WriteLine("Received: {0}", data);
string time = Values[1];
// Console.WriteLine("Time= " + time);
string lat;
string lng;
string speed;
string date;

lat = Values[3];
lng = Values[5];
speed = Values[7];
date = Values[9];

string NewDString = date.Substring(2, 2) + date.Substring(0, 2) + date.Substring(4, 2);

// Console.WriteLine("IMEI= " + IMEI);

// Alternate choice: If the string has been input by an end user, you might
// want to format it according to the current culture:
// IFormatProvider culture = System.Threading.Thread.CurrentThread.CurrentCulture;
string myDate = (NewDString + time).Insert(2, "-").Insert(5, "-").Insert(8, " ").Insert(11, ":").Insert(14, ":");


double latDeg = Convert.ToDouble(Convert.ToDouble(lat).ToString().Substring(0, 2));
double latMin = Convert.ToDouble(Convert.ToDouble(lat).ToString().Substring(2));

double lngDeg = Convert.ToDouble(Convert.ToDouble(lng).ToString().Substring(0, 2));
double lngmin = Convert.ToDouble(Convert.ToDouble(lng).ToString().Substring(2));

double latmap = latDeg + (latMin / 60);
// OldLat=
double lngmap = lngDeg + (lngmin / 60);
//if ((Math.Round(latmap, 3) != Math.Round(OldLat, 3) && Math.Round(lngmap, 3) != Math.Round(OldLng, 3)) || idleRecord > 30)
//{
using (SqlConnection conn = new SqlConnection(ConnStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
// DbCommand also implements IDisposable

// create command with placeholders
cmd.CommandText =
"INSERT INTO T_Tracking " +
"([IMEI], [TrackTime], [Longitude], [Lattitude], [speed],[MapPoint],[SafeAreaID],[GeoFenceID]) " +
"VALUES(@IMEI, @TrackTime, @Longitude, @Lattitude, @speed,@MapPoint,@SafeAreaID,@GeoFenceID)";


SqlParameter p_IMEI = new SqlParameter("@IMEI", IMEI);
cmd.Parameters.Add(p_IMEI);

SqlParameter p_TrackTime = new SqlParameter("@TrackTime", myDate);
cmd.Parameters.Add(p_TrackTime);

SqlParameter p_Longitude = new SqlParameter("@Longitude", lngmap);
cmd.Parameters.Add(p_Longitude);

SqlParameter p_Lattitude = new SqlParameter("@Lattitude", latmap);
cmd.Parameters.Add(p_Lattitude);

SqlParameter p_Speed = new SqlParameter("@speed", speed);
cmd.Parameters.Add(p_Speed);
SqlParameter p_Points = new SqlParameter("@MapPoint", System.Data.SqlDbType.Udt);
p_Points.UdtTypeName = "geometry";
p_Points.Value = GetGeographyFromText("Point(" + lngmap + " " + latmap + ") ");
cmd.Parameters.Add(p_Points);
SqlParameter P_Safe = new SqlParameter("@SafeAreaID", OutsideSafeArea(latmap, lngmap));
cmd.Parameters.Add(P_Safe);
SqlParameter P_GeoFence = new SqlParameter("@GeoFenceID", InsideDangerArea(latmap, lngmap));
cmd.Parameters.Add(P_GeoFence);
// execute
cmd.ExecuteNonQuery();

}
//}
//else
// idleRecord = idleRecord + 1;

}
}
catch (Exception exp) { WriteLog(exp.ToString(), EventLogEntryType.Error); }
}


}
catch { }
}

}
catch (Exception ex)
{
// Console.WriteLine(" >> " + ex.ToString());
}
}
}
}

它工作正常,但问题是性能它是具有5个设备的测试系统它在 10 分钟内消耗了服务器上 95% 的内存可以做什么来优化该代码

谢谢

最佳答案

这里的问题是,每次新的套接字连接进来时,您都会创建一个新线程,即使底层连接已关闭,该线程也永远不会结束。线程过程在 while (true) 循环中用一个包罗万象的异常处理程序包装,因此当套接字连接关闭并抛出 SocketException 时,它会被捕获并忽略,线程过程再次循环.这也将防止套接字对象的垃圾收集,并且可能也是高度 CPU 密集型的。此外,由于那里的 while(true),永远不会调用 main 末尾的清理代码,实际上只会关闭最后一个客户端连接。

您的线程过程应该正确处理异常并在底层套接字连接关闭时停止循环。

关于c# - 具有线程性能的 tcp 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40504627/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com