创建Socket接收Tcp数据,运行一两天左右就会停止运行

点点圈 提交于 2020-01-15 08:29:38

创建Socket接收Tcp数据,运行一两天左右就会停止运行

请大佬帮忙看一下

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace TcpRecevice
{
    public partial class Form1 : Form
    {
        #region 参数
        private static string FTPCONSTR = "";//FTP的服务器地址。
        private static string FTPUSERNAME = "";//FTP服务器的用户名
        private static string FTPPASSWORD = "";//FTP服务器的密码
        //设备列表
        private static List<DevClient> listDev = new List<DevClient>();
        //数据队列
        public static Queue<byte[]> bufferQueues = new Queue<byte[]>();
        //多线程
        Thread DealGpsMessThread;
        Thread CreateJsonThread;
        /// <summary>
        /// 设备客户端类
        /// </summary>
        private class DevClient
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="s">传入连接的Socket</param>
            public DevClient(Socket s)
            {
                this.Client = s;
                this.Handle = s.Handle.ToInt32();
                this.Buffer = new byte[s.ReceiveBufferSize];
                this.RcvTime = DateTime.Now;
                //异步接收
                this.ClientE = new SocketAsyncEventArgs();
                this.ClientE.SetBuffer(this.Buffer, 0, this.Buffer.Length);
                this.ClientE.Completed += ReceiveCompleted;
            }
            //设备Socket
            public Socket Client { get; set; }
            //接收缓冲区
            public byte[] Buffer { get; set; }
            //异步对象
            public SocketAsyncEventArgs ClientE { get; set; }
            //Socket句柄值
            public int Handle { get; set; }
            //最后一次通讯时间
            public DateTime RcvTime { get; set; }
        }
        //线程锁
        private static readonly object locker = new object();
        //主通讯Socket
        private static Socket socketServer = null;
        //数据队列
        public Queue<YYClass> YYClass = new Queue<YYClass>();
        #endregion
        //窗体
        public Form1()
        {
            InitializeComponent();
        }
        //开始监听
        private void button1_Click(object sender, EventArgs e)
        {
            //调用tcp连接
            this.button1.Enabled = false;
            this.button2.Enabled = true;
            this.label1.Enabled = false;
            this.label2.Enabled = false;
            MessageBox.Show("监听已启动");
            //创建链接,监听数据
            Thread TcpListenThread;
            TcpListenThread = new Thread(new ThreadStart(TcpListen));
            TcpListenThread.IsBackground = true;
            TcpListenThread.Start();
            //多线程处理数据
            Receive();
        }
        //创建socket连接,监听数据
        private void TcpListen()
        {
            string str = this.textBox1.Text;
            IPAddress IP = IPAddress.Parse(str);
            int port = Convert.ToInt32(this.textBox2.Text);
            if (socketServer == null)
            {
                try
                {
                    //定义Socket对象,使用TCP协议
                    socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //绑定Socket
                    socketServer.Bind(new IPEndPoint(IP, port));
                    //侦听
                    socketServer.Listen(20);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("创建tcp协议:" + ex.Message);
                    return;
                }
            }
            while (true)
            {
                //若接收到,则创建一个新的Socket与之连接
                Socket newSocket = socketServer.Accept();
                try
                {
                    lock (locker)
                    {
                        DevClient dc = new DevClient(newSocket);
                        listDev.Add(dc);
                        
                        dc.Client.ReceiveAsync(dc.ClientE);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Socket接收:" + ex.Message);
                }
            }
        }
        /// <summary>
        /// 异步接收数据委托事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void ReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                //接收数据
                byte[] dataBytes = new byte[e.BytesTransferred];
                Array.Copy(e.Buffer, 0, dataBytes, 0, e.BytesTransferred);
                if (dataBytes.Length > 0)
                {
                    bufferQueues.Enqueue(dataBytes);
                }
                Thread.Sleep(10);
            }
            catch (Exception ex)
            {
                MessageBox.Show("异步接收数据:" + ex.Message);
            }
        }

        //多线程处理数据
        public void Receive()
        {
            //解析数据
            DealGpsMessThread = new Thread(new ThreadStart(DealBuffer));
            DealGpsMessThread.IsBackground = true;
            DealGpsMessThread.Start();
            //生成json文件
            CreateJsonThread = new Thread(new ThreadStart(CreateJson));
            CreateJsonThread.IsBackground = true;
            CreateJsonThread.Start();
        }

        //处理Buffer
        private void DealBuffer()
        {
            while (true)
            {
                try
                {
                    if (bufferQueues.Count > 0)
                    {
                        byte[] buffer = bufferQueues.Dequeue();
                        try
                        {
                            if (buffer != null && buffer[0] == 126 && buffer[1] == 2 && buffer[2] == 0)
                            {
                                //byte[]转16进制
                                StringBuilder strBuider = new StringBuilder();
                                for (int i = 0; i < buffer.Length; i++)
                                {
                                    if (((int)buffer[i]).ToString("X2") == "7E" || ((int)buffer[i]).ToString("X2") == "7e")
                                    {
                                        strBuider.Append("7D02");
                                        continue;
                                    }
                                    if (((int)buffer[i]).ToString("X2") == "7D" || ((int)buffer[i]).ToString("X2") == "7d")
                                    {
                                        strBuider.Append("7D01");
                                        continue;
                                    }
                                    strBuider.Append(((int)buffer[i]).ToString("X2"));
                                }
                                string str = strBuider.ToString();
                                string res = str.Substring(4, str.Length - 8);
                                
                                //16进制数组
                                string[] byteArry = new string[res.Length / 2];
                                for (int i = 0; i < res.Length / 2; i++)
                                {
                                    if (i == 0)
                                    {
                                        byteArry[i] = res.Substring(0, 2);
                                    }
                                    else
                                    {
                                        byteArry[i] = res.Substring(i * 2, 2);
                                    }
                                }

                                YYClass yy = new YYClass();
                                //手机号
                                string phone = byteArry[4] + byteArry[5] + byteArry[6] + byteArry[7] + byteArry[8] + byteArry[9];
                                if (phone.StartsWith("0"))
                                {
                                    phone = phone.Substring(1, phone.Length - 1);
                                }
                                //纬度
                                decimal Yres = Convert.ToInt64(byteArry[20] + byteArry[21] + byteArry[22] + byteArry[23], 16);
                                string Y = (Yres / 1000000).ToString();
                                //经度
                                decimal Xres = Convert.ToInt64(byteArry[24] + byteArry[25] + byteArry[26] + byteArry[27], 16);
                                string X = (Xres / 1000000).ToString();
                                //高程0352
                                string Z = Convert.ToInt64(byteArry[28] + byteArry[29], 16).ToString();
                                //速度
                                decimal SP = Convert.ToInt64(byteArry[30] + byteArry[31], 16);
                                string SPEED = (SP / 10).ToString();
                                //方向
                                string DIR = Convert.ToInt64(byteArry[32] + byteArry[33], 16).ToString();
                                //时间
                                string TIME = ("20" + byteArry[34] + "-" + byteArry[35] + "-" + byteArry[36] + " " + byteArry[37] + ":" + byteArry[38] + ":" + byteArry[39]).ToString();


                                //获取车牌
                                string fileRes = File.ReadAllText(@"C:\\data\\res1.txt");
                                JObject jobj = (JObject)JsonConvert.DeserializeObject(fileRes.ToString());
                                Regex regNum = new Regex("^[0-9]");
                                List<PhoneAndChepai> PhoneAndChepai = new List<PhoneAndChepai>();
                                List<string> chepaiList = new List<string>();
                                for (int i = 0; i < jobj["Data"].Count(); i++)
                                {
                                    PhoneAndChepai aa = new PhoneAndChepai();
                                    string cp = jobj["Data"][i]["VEHICLENUM"].ToString();
                                    if (regNum.IsMatch(cp) && cp.Length > 8)
                                    {
                                        cp = jobj["Data"][i]["VEHICLENUM"].ToString().Substring(4);
                                    }
                                    aa.chepai = cp;
                                    //电话
                                    string dh = jobj["Data"][i]["SIM"].ToString();
                                    aa.phone = dh;
                                    //ID
                                    string id = jobj["Data"][i]["DEVID"].ToString();
                                    aa.id = id;
                                    PhoneAndChepai.Add(aa);
                                }
                                var cph = PhoneAndChepai.Where(x => x.phone == phone).ToList();
                                string chepai = cph[0].chepai.ToString();

                                yy.ID = cph[0].id.ToString();//唯一编号
                                yy.PLATENO = chepai;//车牌
                                yy.POSTYPE = "1";//定位类型
                                yy.X = X;//经度
                                yy.Y = Y;//纬度
                                yy.Z = Z;//高程
                                yy.DIR = DIR;//方向
                                yy.SPEED = SPEED;//速度
                                yy.TIME = TIME;//时间
                                yy.PHONE = phone;//手机号
                                YYClass.Enqueue(yy);//插入队列
                            }
                        }
                        catch (Exception ex)
                        {
                            //MessageBox.Show("处理Buffer:" + ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //MessageBox.Show("处理Buffer:" + ex.Message);
                }
            }
        }
        //生成json文件
        private void CreateJson()
        {
            while (true)
            {
                if (YYClass.Count > 0)
                {
                    YYClass Info = YYClass.Dequeue();
                    try
                    {
                        List<YYClass> list = new List<YYClass>();
                        list.Add(Info);
                        if (list.Count > 0)
                        {
                            //保存文件
                            try
                            {
                                StringBuilder sb = new StringBuilder();
                                sb.Append("{");
                                sb.Append("\"record\":[");
                                sb.Append("{");
                                sb.Append("\"id\":\"" + list[0].ID + "\",");      //设备唯一编号,行政区划代码+序列
                                sb.Append("\"plateno\":\"" + list[0].PLATENO + "\","); //车牌号码
                                sb.Append("\"postype\":1,"); //定位类型:1、北斗,2、GPS
                                sb.Append("\"x\":" + list[0].X + ",");       //定位经度
                                sb.Append("\"y\":" + list[0].Y + ",");       //定位纬度
                                sb.Append("\"speed\":" + list[0].SPEED + ",");   //速度
                                sb.Append("\"dir\":" + list[0].DIR + ",");     //方向
                                sb.Append("\"z\":" + list[0].Z + ",");       //高程
                                sb.Append("\"time\":\"" + list[0].TIME + "\"");    //定位时间
                                sb.Append("},");
                                string res2 = sb.ToString();
                                string res1 = res2.Substring(0, sb.Length - 1) + "]}";
                                //获取当前时间的时间戳
                                DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
                                long TimeStamp = (long)(DateTime.Now - startTime).TotalMilliseconds;
                                //写入到文件
                                if (!Directory.Exists(@"C:\json"))
                                {
                                    Directory.CreateDirectory(@"C:\json");
                                }
                                //文件名称

                                File.WriteAllText(@"C:\json\140100" + TimeStamp + ".json", res1.ToString());
                                Thread.Sleep(200);

                                //实现FTP上传
                                string path = @"C:\json\140100" + TimeStamp + ".json";
                                if (File.Exists(path))
                                {
                                    var client = new WebClient();
                                    client.Credentials = new NetworkCredential(FTPUSERNAME, FTPPASSWORD);//用户名和密码
                                    client.BaseAddress = FTPCONSTR;//ftp地址
                                    string ftpPath = client.BaseAddress + "/data/140100" + TimeStamp + ".json";//上传fptp路径
                                    string returnPath = "";
                                    try
                                    {
                                        client.UploadFile(ftpPath, path);
                                        returnPath = ftpPath;
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show("上传ftp:" + ex.Message);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show("保存文件:" + ex.Message);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("保存json文件:" + ex.Message);
                    }
                }
                else
                {
                    Thread.Sleep(100);
                }

            }
        }

        //定时器每6小时清除缓存
        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                string nowDate = DateTime.Now.ToString("HH:mm:ss");
                if (nowDate == "00:00:00" || nowDate == "06:00:00" || nowDate == "12:00:00" || nowDate == "18:00:00")
                {
                    //释放内存
                    ClearMemory();
                    listDev.Clear();
                    //删除文件
                    DelFile();
                    Thread.Sleep(60000);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("定时器:" + ex.Message);
            }
        }
        //删除文件
        public static void DelFile()
        {
            try
            {
                DirectoryInfo dyInfo = new DirectoryInfo(@"C:\json");
                //获取文件夹下所有的文件
                foreach (FileInfo feInfo in dyInfo.GetFiles())
                {
                    //判断文件日期是否小于今天,是则删除
                    if (feInfo.CreationTime < DateTime.Today)
                    {
                        feInfo.Delete();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("删除文件:" + ex.Message);
            }
        }
        //关闭窗体
        private void button2_Click(object sender, EventArgs e)
        {
            DialogResult r = MessageBox.Show("确定要退出程序?", "操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (r == DialogResult.OK)
            {
                Application.ExitThread();
            }
        }
        /// <summary>      
        /// 释放内存      
        /// </summary> 
        [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
        public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
        public static void ClearMemory()
        {
            try
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {
                    SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("释放内存:" + ex.Message);
            }
        }
        //实体类
        public class PhoneAndChepai
        {
            public string chepai { get; set; }
            public string phone { get; set; }
            public string id { get; set; }
        }
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!