Пример #1
0
        //保存文件,16进制,封装开头是0xAA,结尾是0x55
        public void StoreDataToFile(int intDeviceID, byte[] bytes)
        {
            string filename = DateTime.Now.ToString("yyyy-MM-dd") + "--" + DateTime.Now.Hour.ToString() + "-" + DateTime.Now.Minute.ToString() + "-" + DateTime.Now.Second.ToString() + "--" + intDeviceID.ToString();//以日期时间命名,避免文件名重复

            byte[] fileStartAndEnd = new byte[2] {
                0xAA, 0x55
            };                                                  //保存文件的头是AA,尾是55
            string     path = @"D:\\Data\\" + filename + ".dat";
            FileStream F    = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);

            F.Write(fileStartAndEnd, 0, 1);
            F.Write(bytes, 0, bytes.Length);
            F.Write(fileStartAndEnd, 1, 1);
            F.Flush();
            F.Close();
            //StatusBox.Text = "文件保存成功";
            Net_DB.addsensorad(intDeviceID, DateTime.Now.ToString(), path);
        }
Пример #2
0
        //接收数据
        private void OnReceive(IAsyncResult ar)
        {
            byte[] ID          = new byte[4];//设备的ID号
            int    intdeviceID = 0;

            int[] cfg = new int[5];//存储从数据库读取的设备配置参数
            try
            {
                Socket clientSocket = (Socket)ar.AsyncState;//此处获取数据大小

                //获取客户端信息,包括了IP地址、端口
                string strIP   = (clientSocket.RemoteEndPoint as IPEndPoint).Address.ToString();
                string strPort = (clientSocket.RemoteEndPoint as IPEndPoint).Port.ToString();
                //test
                string strAddress = clientSocket.RemoteEndPoint.ToString();

                DataItem dataitem = (DataItem)htClient[strAddress]; //取出address对应的dataitem
                //获取接收的数据长度,注意此处的停止接收,后面必须继续接收,否则不会接收数据的。
                int bytesRead = clientSocket.EndReceive(ar);        //接收到的数据长度
                if (bytesRead > 0)                                  //打印数据
                {
                    string str    = byteToHexStr(dataitem.SingleBuffer);
                    string strrec = str.Substring(0, bytesRead * 2);
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "从硬件" + strAddress + "设备号--" + dataitem.intDeviceID + "接收到的数据长度是" + bytesRead.ToString() + "数据是" + strrec + "\n"); //把接收的数据打印出来

                    if (checkIsHeartPackage(dataitem.SingleBuffer))
                    {
                        if (dataitem.intDeviceID == 0)//只判断新地址的心跳包,避免重复检测
                        {
                            //设备的ID字符串
                            ID[0]       = dataitem.SingleBuffer[3];
                            ID[1]       = dataitem.SingleBuffer[4];
                            ID[2]       = dataitem.SingleBuffer[5];
                            ID[3]       = dataitem.SingleBuffer[6];
                            intdeviceID = byteToInt(ID);

                            string oldAddress = checkIsHaveID(intdeviceID);            //得到当前ID对应的旧地址

                            if (oldAddress != null)                                    //若存在,把旧地址的属性复制到新地址上
                            {                                                          //!!!由于掉线,新dataitem属性要继承旧设备,只需要更新网络属性,如IP、port、socket等
                                DataItem olddataitem = (DataItem)htClient[oldAddress]; //取出当前数据IP对应的dataitem

                                dataitem.byteDeviceID       = ID;
                                dataitem.intDeviceID        = intdeviceID;
                                dataitem.strIP              = strIP;
                                dataitem.strPort            = strPort;
                                dataitem.datalength         = olddataitem.datalength;      //继承旧属性
                                dataitem.socket             = clientSocket;
                                dataitem.byteAllData        = olddataitem.byteAllData;     //继承旧属性
                                dataitem.currentsendbulk    = olddataitem.currentsendbulk; //继承旧属性
                                dataitem.uploadGroup        = olddataitem.uploadGroup;     //继承旧属性
                                dataitem.isGetADNow         = olddataitem.isGetADNow;
                                dataitem.isWaked            = 1;
                                dataitem.CmdStage           = olddataitem.CmdStage;           //继承旧属性
                                dataitem.isSendDataToServer = olddataitem.isSendDataToServer; //继承旧属性
                                dataitem.CmdNum             = olddataitem.CmdNum;             //继承旧属性
                                dataitem.SingleBuffer       = new byte[perPackageLength];
                                dataitem.strAddress         = strAddress;

                                dataitem.CmdbulkHex    = olddataitem.CmdbulkHex;    //要发送的命令数目--16进制//继承旧属性
                                dataitem.CapTimeHour   = olddataitem.CapTimeHour;   //继承旧属性
                                dataitem.CapTimeMinute = olddataitem.CapTimeMinute; //继承旧属性
                                dataitem.OpenTime      = olddataitem.OpenTime;      //继承旧属性
                                dataitem.CloseTime     = olddataitem.CloseTime;     //继承旧属性

                                htClient.Remove(oldAddress);                        //删除旧地址的键值对
                                htClient[strAddress] = dataitem;

                                string time = DateTime.Now.ToString();
                                //把信息存入数据库
                                Net_DB.addsensorinfo(intdeviceID, strIP, strPort, time, dataitem.isWaked);

                                Log.Debug("ID为" + intdeviceID + "--地址" + strAddress + "已存储");
                            }
                            else
                            {
                                //若不存在,属于全新地址,更新ID号
                                dataitem.intDeviceID  = intdeviceID;
                                dataitem.byteDeviceID = ID;
                                cfg = Net_DB.readsensorcfg(intdeviceID);//从数据库读取设备的配置参数
                                if (cfg != null)
                                {
                                    dataitem.CmdbulkHex    = cfg[0];//要发送的命令数目--16进制
                                    dataitem.CapTimeHour   = cfg[1];
                                    dataitem.CapTimeMinute = cfg[2];
                                    dataitem.OpenTime      = cfg[3];
                                    dataitem.CloseTime     = cfg[4];
                                }
                                //开启命令发送定时器
                                if (cmdTimer.Enabled != true)
                                {
                                    cmdTimer.Start();
                                }

                                string time = DateTime.Now.ToString();
                                //把信息存入数据库
                                Net_DB.addsensorinfo(intdeviceID, strIP, strPort, time, dataitem.isWaked);
                            }
                        } //if (dataitem.intDeviceID == 0)
                    }     //end if (checkIsHeartPackage())

                    //设备进入低功耗模式后,断开网络,从哈希表中移除
                    //如果是暂时关闭,则不能从哈希表中移除
                    if (checkIsOffLine(dataitem.SingleBuffer))
                    {
                        //更新数据库,把isWaked置0
                        dataitem.isWaked = 0;
                        Net_DB.addsensorinfo(dataitem.intDeviceID, strIP, strPort, DateTime.Now.ToString(), dataitem.isWaked);
                        clientSocket.Shutdown(SocketShutdown.Both);
                        clientSocket.Close();
                        htClient.Remove(intdeviceID);
                        System.Diagnostics.Debug.WriteLine("设备已断开连接,进入低功耗模式");
                    }
                    if (checkIsGPSsetOK(dataitem.SingleBuffer))
                    {
                        dataitem.CmdNum++;
                        System.Diagnostics.Debug.WriteLine("设定GPS采样时间成功");
                        Log.Debug("设备号为" + dataitem.intDeviceID + "设定GPS采样时间成功");
                    }
                    if (checkIsGPSReadOK(dataitem.SingleBuffer))
                    {
                        dataitem.CmdNum++;
                        System.Diagnostics.Debug.WriteLine("读取GPS当前时间成功");
                        Log.Debug("设备号为" + dataitem.intDeviceID + "读取GPS当前时间成功");
                    }

                    if (checkIsOpenAndCloseTime(dataitem.SingleBuffer))
                    {
                        dataitem.CmdNum++;
                        System.Diagnostics.Debug.WriteLine("关闭时长设置成功");
                        Log.Debug("设备号为" + dataitem.intDeviceID + "关闭时长设置成功");

                        //该设备需要设置或者查询的命令已发完,剩下的是上传
                        dataitem.CmdbulkHex = 0;
                    }
                    if (checkIsADstart(dataitem.SingleBuffer))
                    {
                        System.Diagnostics.Debug.WriteLine("AD采样开始");
                    }

                    //检查AD采样是否结束
                    if (checkIsADfinished(dataitem.SingleBuffer))
                    {
                        System.Diagnostics.Debug.WriteLine("AD采样结束,准备上传AD数据");
                        //!!!在此处记录该设备的一套命令已发完,把CmdbulkHex置0;若所有设备的命令发完(包括AD采样),则关闭定时器
                        dataitem.CmdStage = 1;

                        Log.Debug("设备号为" + dataitem.intDeviceID + "AD采样结束,CmdStage设为1");
                        //如果是立即采样,则采样完成后上传AD数据
                        if (dataitem.isGetADNow == true)
                        {
                            UploadADdata(dataitem.strAddress);
                        }
                    }

                    //处理AD数据(收到纯数据时保存到一个60万大小的数组中)
                    if (checkIsPureData(dataitem.SingleBuffer))
                    {
                        dataitem.currentsendbulk++;

                        for (int i = 7; i < perPackageLength - 1; i++)//将上传的包去掉头和尾的两个字节后,暂时存储在TotalData[]中
                        {
                            dataitem.byteAllData[dataitem.datalength++] = dataitem.SingleBuffer[i];
                        }
                        if (dataitem.datalength == g_datafulllength)//1000*600 = 600000;
                        {
                            StoreDataToFile(dataitem.intDeviceID, dataitem.byteAllData);
                            //复位变量
                            //dataitem.totalsendbulk = 0;
                            dataitem.currentsendbulk    = 0;
                            dataitem.isSendDataToServer = false;
                            System.Diagnostics.Debug.WriteLine("数据采集完毕");
                            //progressBar1.Value = 0;
                            //!!!若所有设备的命令发完(包括AD采样),设置一个属性
                            //!!!还要加一个判断,若哈希表中的所有设备都已发完命令。就可以关闭定时器了
                            dataitem.CmdStage = 3;
                            //test
                            Log.Debug("设备号为" + dataitem.intDeviceID + "数据采集完毕,CmdStage设为3");
                            if (dataitem.isGetADNow == true)
                            {
                                //立即采样结束后恢复采样时刻
                                byte[] cmdCapTime = cmdItem.CmdSetCapTime;
                                cmdCapTime[9]  = (byte)dataitem.CapTimeHour;
                                cmdCapTime[10] = (byte)dataitem.CapTimeMinute;
                                SendCmdSingle(cmdCapTime, dataitem.byteDeviceID, dataitem.socket, 1);

                                dataitem.isGetADNow = false;//立即采样的数据上传完成后,将属性复位为false
                            }
                        }
                    }

                    if (checkIsAllCmdStage1()) //所有设备采样完成,关闭定时器,可以进行上传了
                    {
                        cmdTimer.Stop();       //add 5-12
                        Log.Debug("所有设备采样完成,关闭定时器,开始分组");
                        setTaskGroup();

                        if (checkIsAllCmdStage2())//所有设备的分组属性设置完,上传第0组,激活分段上传过程
                        {
                            Log.Debug("分组完成,开始上传");
                            UploadADdataByGroup(currentUploadGroup);
                        }
                    }

                    //检查是否当前组都下线且下一组都上线
                    if (checkCurrentOffLineAndNextOnLine(currentUploadGroup))
                    {
                        //当前组已经发完并下线,可以给下一组发送上传命令了
                        Log.Debug("当前组已经发完并下线,可以给下一组发送上传命令了");

                        //将当前组(第0组不用恢复)设备恢复关闭时长
                        byte[] cmdSetOpenAndCloseTime = cmdItem.CmdSetOpenAndCloseTime;
                        cmdSetOpenAndCloseTime[9]  = (byte)(2 * dataitem.OpenTime >> 8);
                        cmdSetOpenAndCloseTime[10] = (byte)(2 * dataitem.OpenTime & 0xFF);
                        cmdSetOpenAndCloseTime[11] = (byte)(2 * dataitem.CloseTime >> 8);
                        cmdSetOpenAndCloseTime[12] = (byte)(2 * dataitem.CloseTime & 0xFF);
                        SendCmdSingle(cmdSetOpenAndCloseTime, dataitem.byteDeviceID, dataitem.socket, 1);

                        currentUploadGroup += 1;

                        UploadADdataByGroup(currentUploadGroup);
                    }

                    if (checkIsAllCmdStage3())
                    {
                        foreach (DictionaryEntry de in htClient)
                        {
                            DataItem dataitem1 = (DataItem)de.Value;
                            if (dataitem1.CmdStage == 3)//add 5-13
                            {
                                dataitem.CmdStage = 0;
                            }
                        }

                        Log.Debug("所有设备数据传完,CmdStage置0");
                    }

                    if (checkIsAllOffLine())//add 5-11
                    {
                        htClient.Clear();
                        Log.Debug("清空哈希表");
                    }

                    //把数据上传到服务器
                    if (dataitem.isSendDataToServer == true)
                    {
                        SendCmdSingle(SetADcmd(dataitem.currentsendbulk), dataitem.byteDeviceID, dataitem.socket, 1);//发送下一包的命令
                        System.Diagnostics.Debug.WriteLine("第" + dataitem.currentsendbulk + "包");
                        Log.Debug("设备号为" + dataitem.intDeviceID + "第" + dataitem.currentsendbulk + "包");
                    }
                }

                else if (bytesRead == 0)//设备自己关闭socket
                {
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                    Log.Debug(dataitem.strAddress + "设备自己关闭socket");
                }
                //需要持续接收
                clientSocket.BeginReceive(dataitem.SingleBuffer, 0, dataitem.SingleBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
            }
            catch (Exception ex)
            {
                string error = DateTime.Now.ToString() + "出错信息:" + "---" + ex.Message + "\n";
                Log.Debug(ex);
                System.Diagnostics.Debug.WriteLine(error);
            }
        }