using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; namespace DataGateWayProject { class GetData_From_iCos { static UdpClient client; static IPEndPoint ep; Form1 F1 = new Form1(); LogFileCreate LFC = new LogFileCreate(); System.Timers.Timer timer_GetData = new System.Timers.Timer(); public static ConcurrentDictionary Key_Value_Dic = new ConcurrentDictionary(); public static ConcurrentDictionary TagName_Matching_Dic = new ConcurrentDictionary(); public string GetTagValue(string TagKey) { string Value_Return = ""; Value_Return = Key_Value_Dic[TagKey]; if(Value_Return=="") { Value_Return = "0"; } return Value_Return; // Example only. } public void GetValueTimer() { // System.Timers.Timer timer = new System.Timers.Timer(); timer_GetData.Interval = 5000; timer_GetData.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed); timer_GetData.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); timer_GetData.Start(); } public void SetTagValue(string TagName, float Tagvalue) { Readini Ri = new Readini(); Ri.ReadData(); // ini의 설정값을 불러옴. int Col = 2; byte[] byteArr1; byte[] byteArr2; byte[] TmpByte = new byte[1024]; //var client = new UdpClient(); //IPEndPoint ep = new IPEndPoint(IPAddress.Parse(Ri.IP1), Convert.ToInt32(Ri.Port1)); // endpoint where server is listening //client.Connect(ep); string[] tmp = new string[2]; tmp[0] = TagName; tmp[1] = Convert.ToString(Tagvalue); byteArr1 = System.Text.Encoding.Default.GetBytes(tmp[1]); foreach (byte words in byteArr1) // ex)Tag1 -> T a g 1로 .... { TmpByte[Col] = words; Col++; } TmpByte[Col] = 0x3D; Col++; byteArr2 = System.Text.Encoding.Default.GetBytes(tmp[2]); foreach (byte words in byteArr2) // ex)Tag1 -> T a g 1로 .... { TmpByte[Col] = words; Col++; } TmpByte[Col] = 0x00; TmpByte[1023] = CheckSum(TmpByte); client.Send(TmpByte, 1024); try { var receive_WriteTagValue = client.Receive(ref ep); } catch(Exception e) { LFC.Log("값 설정 실패 = " + e); } } public byte CheckSum(byte[] CheckData) { byte Sum = 00; for (int bytenum = 0; bytenum < 1023; bytenum++) { Sum += CheckData[bytenum]; } Sum = (byte)(Sum & 0xFF); return Sum; } public void ReadTag() { Readini Ri = new Readini(); Ri.ReadData(); // ini의 설정값을 불러옴. //var client = new UdpClient(); //20170116 //IPEndPoint ep = new IPEndPoint(IPAddress.Parse(Ri.IP1), Convert.ToInt32(Ri.Port1)); // endpoint where server is listening //20170116 //client.Connect(ep); //20170116 byte[,] tmp = Read_TagSetFile(); int Num_Row = tmp.Length / 1024; try { for (int RowNum = 0; RowNum < Num_Row; RowNum++) { byte[] Send_data = new byte[1024]; for (int InsertData = 0; InsertData < 1023; InsertData++) { Send_data[InsertData] = tmp[RowNum, InsertData]; } byte checksum = CheckSum(Send_data); Send_data[1023] = checksum; client.Send(Send_data, 1024); string tmpsendpacket = ""; //보낸 packet LFC.Log("보낸 패킷"); foreach (byte tagPacket_send in Send_data) { tmpsendpacket += tagPacket_send + " "; } LFC.Log(tmpsendpacket); var receivedData1 = client.Receive(ref ep); LFC.Log("Tag에 대한 Packet"); string tmppacket = ""; foreach(byte tagPacket in receivedData1) { tmppacket += tagPacket + " "; } LFC.Log(tmppacket); } } catch (Exception e) { LogFileCreate LFC = new LogFileCreate(); LFC.Log("등록에러 = " + e); } } public byte[] Alive_Check() { byte[] Send_Alive = new byte[1024]; Send_Alive[0] = 0x03; Send_Alive[1023] = 0x03; return Send_Alive; } public string iCos3_Conn() { Readini Ri = new Readini(); LogFileCreate LFC = new LogFileCreate(); Ri.ReadData(); // ini의 설정값을 불러옴. bool Re_Conn_Check = false; client = new UdpClient(); var receivedData = new byte[1024]; string Result_Conn_iCos = ""; // 태그 값 등록_20170123 ..프로그램 시작시에 아에 태그명의 값을 0으로 설정 string[] sArray = File.ReadAllLines("TagSetFile.csv", Encoding.Default); for (int i = 0; i < sArray.Length; i++) // { string[] tmp = sArray[i].Split(','); // tmp[0] = index, tmp[1] = Tag명. Key_Value_Dic.TryAdd(tmp[1], "0"); } //IPEndPoint ep = new IPEndPoint(IPAddress.Parse(Ri.IP1), Convert.ToInt32(Ri.Port1)); // endpoint where server is listening ep = new IPEndPoint(IPAddress.Parse(Ri.IP1), Convert.ToInt32(Ri.Port1)); // endpoint where server is listening byte[] Send_Alive = Alive_Check(); // 생존 프로토콜 생성 bool Conn_Flag = false; bool Error_Conn = false; string tmplogstring = ""; try { client.Connect(ep); // 접속 client.Client.SendTimeout = 5000; // send Timeout 5초 설정 client.Client.ReceiveTimeout = 5000; // receive timeout 5초 설정 client.Send(Send_Alive, 1024); receivedData = client.Receive(ref ep); foreach (byte tmplog in receivedData) { tmplogstring += tmplog; } LFC.Log(tmplogstring); foreach (byte tmp in receivedData) { if (tmp == 0x06) { //LogTxt.Text += "통신 오류가 발생하였습니다. 다시 시도해주세요." + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine; Conn_Flag = true; client.Close(); Error_Conn = true; } break; } } catch (Exception e1) { LFC.Log("접속실패 " + e1 + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); Result_Conn_iCos = "FAIL"; Re_Conn_Check = true; } if (Re_Conn_Check == true) { for (int Re_Conn = 0; Re_Conn < 2; Re_Conn++) { try { LFC.Log("재접속 시도 중 ...접속 시도 횟수 = " + Re_Conn + " = " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); //LogTxt.Text += "재접속 시도 중 ...접속 시도 횟수 = " + Re_Conn + " = " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine; client.Connect(ep); // 접속 client.Send(Send_Alive, 1024); receivedData = client.Receive(ref ep); if (receivedData != null) { break; } } catch { LFC.Log("재접속 실패 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); //LogTxt.Text += "재접속 실패 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine; Result_Conn_iCos = "FAIL"; } } } int len = receivedData.Length; // 수신받은데이터 길이 확인 byte sum = CheckSum(receivedData); // 수신받은 데이터 체크썸 확인 byte rec = receivedData[1023]; string packetstring = ""; foreach (byte log in receivedData) { packetstring += log + " "; } // LogTxt.Text += "수신받은 데이터의 체크섬 = " + rec + Environment.NewLine; //LogTxt.Text += "합산 = " + sum + Environment.NewLine; // LogTxt.Text += "길이 = " + len + Environment.NewLine; if (receivedData[1023] != sum || receivedData[0] == 0 || len != 1024 || Error_Conn == true) // CheckSum 과 길이 체크. { LFC.Log("체크섬 = " + Convert.ToString(sum)); LFC.Log("길이 = " + Convert.ToString(len)); LFC.Log("접속 실패 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); Result_Conn_iCos = "FAIL"; } else { LFC.Log("접속 성공 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); Result_Conn_iCos = "SUCCESS"; } return Result_Conn_iCos; } public byte[,] Read_TagSetFile() { UnicodeEncoding enc = new UnicodeEncoding(); string[] TagSum = new string[2]; string[] CSVReadLine = new string[2]; // byte Tmp_Korean_byte = new byte(); int count = 0; int One_Raw_Count = 0; int Col = 4; int Row = 0; int TotalCount = 0; int Length_Check = 0; //StreamReader sr = new StreamReader("TagSetFile.csv", Encoding.GetEncoding("euc-kr")); // 파일 한번만 읽기. string[] sArray = File.ReadAllLines("TagSetFile.csv", Encoding.Default); double Rotate = Math.Ceiling(Convert.ToDouble(sArray.Length) / 25); // Tag의 개수는 25개씩 실어서 보낼 것임. 따라서 25로 나눠 프레임을 몇번 보낼지 결정. double c = sArray.Length / 25; byte[,] TmpByte = new byte[Convert.ToInt32(Rotate), 1024]; // Row의 개수는 Rotate의 수와 같다. for (int i = 0; i < sArray.Length; i++) // { byte[] byteArr; string[] tmp = sArray[i].Split(','); // tmp[0] = index, tmp[1] = Tag명. TagName_Matching_Dic.TryAdd(tmp[0], tmp[1]); //char[] Tmp_Tag = tmp[1].ToCharArray(); //tmp[1] 의 ASCII코드 하나하나를 Hex로 바꾸기위한 과정 byteArr = System.Text.Encoding.Default.GetBytes(tmp[1]); foreach (byte words in byteArr) // ex)Tag1 -> T a g 1로 .... { TmpByte[Row, Col] = words; Col++; } if (sArray.Length < 25) // TAG가 25개 이하인경우.. ROW는 1개 { Length_Check++; if (sArray.Length == 1) { TmpByte[Row, Col] = 00; // 01로 Tag명을 구분함. TmpByte[Row, 0] = 0x08; byte sum = CheckSum2(TmpByte, Row); TmpByte[Row, 1023] = sum; } else if (One_Raw_Count < sArray.Length - 1) { TmpByte[Row, Col] = 01; // 01로 Tag명을 구분함. Col++; One_Raw_Count++; } else { TmpByte[Row, Col] = 00; // 01로 Tag명을 구분함. TmpByte[Row, 0] = 0x08; byte sum = CheckSum2(TmpByte, Row); TmpByte[Row, 1023] = sum; } } else // TAG가 25개 이상인 경우... { TmpByte[Row, Col] = 01; // 01로 Tag명을 구분함. Col++; } count++; if (Length_Check == 0) { if (count == 25 || (TotalCount == System.Math.Truncate(c)) && (count == sArray.Length % 25)) // Tag 25개가 쌓였을때. { //string Seq_Hex = toHex(Row); //uint num = uint.Parse(Seq_Hex, System.Globalization.NumberStyles.AllowHexSpecifier); //byte[] floatVals = BitConverter.GetBytes(num); TmpByte[Row, 0] = 0x08; if (Row == 0) { TmpByte[Row, 1] = 0x02; } else { TmpByte[Row, 1] = 0x00; } TmpByte[Row, 2] = Convert.ToByte(Row); TmpByte[Row, 3] = 0x00; Col--; // 맨 끝의 Col 을 00으로 바꾸기 위해 1칸 줄임. TmpByte[Row, Col] = 0x00; // TmpByte의 맨끝에 00을 추가함. byte sum = CheckSum2(TmpByte, Row); TmpByte[Row, 1023] = sum; count = 0; // 25번 카운트 후 다시 0으로. Col = 4; // Column 0으로 초기화 Row++; // Row는 1증가 TotalCount++; } } } return TmpByte; } public byte CheckSum2(byte[,] CheckData, int Row) { byte Sum = 00; for (int bytenum = 0; bytenum < 1023; bytenum++) { Sum += CheckData[Row, bytenum]; } Sum = (byte)(Sum & 0xFF); return Sum; } public byte Error_Check(byte[,] CheckData, int Row) { byte Sum = 00; return Sum; } bool mConnecting = false; // delegate void TimerEventFiredDelegate(); /// ///**************************************iCos 통신 타이머************************************/ /// iCos와 통신해서 값을 받아오도록 하는 동작을 관할하는 타이머이다. /// void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (mConnecting == false) { mConnecting = true; LogFileCreate LFC = new LogFileCreate(); //LFC.Log("***타이머 스레드 동작 시작***"); Work(); //timer.Enabled = false; mConnecting = false; // LFC.Log("***타이머 스레드 동작 중단***"); } } //**************************************************************************************/ private My_TimerThread MTT = new My_TimerThread(); private void Work() { try { byte[] a = new byte[1024]; // int tmp_hour = Convert.ToInt32(DateTime.Now.ToString("HH")); int tmp_min = Convert.ToInt32(DateTime.Now.ToString("mm")); for (int i = 0; i < 50; i++) { byte[] Obtain_Value = new byte[1024]; bool TagCheck = false; bool Tag_Value_Check = false; Obtain_Value[0] = 0x02; Obtain_Value[1023] = 0x02; client.Send(Obtain_Value, 1024); var receivedData2 = client.Receive(ref ep); ////**************************************패킷 확인 부************************************/ //// 통신 패킷을 확인하기 위한 부분이다. //// 00시 03시 06시 09시 12시 15시 18시 21시에 iCos와 통신하는 패킷을 로그로 남기도록 한다. //if ((tmp_hour == 0 || tmp_hour == 3 || tmp_hour == 6 || tmp_hour == 9 || tmp_hour == 12 || tmp_hour == 15 || tmp_hour == 18 || tmp_hour == 21) && (tmp_min == 00)) //{ // string tmpsendpacket_t = ""; // foreach (byte tagPacket_send in receivedData2) // { // tmpsendpacket_t += tagPacket_send + " "; // } // LFC.Log(tmpsendpacket_t); //} ////**************************************************************************************/ int Count = 0; string Tag_Name = ""; string Tag_Value = ""; foreach (byte Raw_Packet in receivedData2) { Count++; if (Count < 8) /// 패킷을 저장할 것인지 버릴지 판단 { continue; } else { if (Raw_Packet == 0x3d) { Key_Value_Dic.TryAdd(TagName_Matching_Dic[Tag_Name], "0"); TagCheck = true; Tag_Value_Check = true; // 이때부터 Tag value의 값을 수집 continue; } if (Raw_Packet == 0x01) { // NULL 데이터가 들어왔을때 처리해주는 부분. // 일단 값은 0으로 해준다. if(Tag_Value == "") { Tag_Value = "0"; } Key_Value_Dic.AddOrUpdate(TagName_Matching_Dic[Tag_Name], "0", (Tag_Name2, currentValue2) => Tag_Value); Tag_Name = ""; Tag_Value = ""; TagCheck = false; Tag_Value_Check = false; continue; } if (Raw_Packet == 0x00) { // NULL 데이터가 들어왔을때 처리해주는 부분. // 일단 값은 0으로 해준다. if (Tag_Value == "") { Tag_Value = "0"; } Key_Value_Dic.AddOrUpdate(TagName_Matching_Dic[Tag_Name], "0", (Tag_Name2, currentValue2) => Tag_Value); break; } if (TagCheck == false) { // Tag명을 만들기.. Tag명을 만들기 위해서 Hex값을 ASCII코드로 변환해야함. char Tag_Name_Tmp = Convert.ToChar(Raw_Packet); Tag_Name += Tag_Name_Tmp.ToString(); // Tag_Name 은 Dictionary에서 Key값이 될 것이다. } else if (Tag_Value_Check == true) { char Tag_Value_Tmp = Convert.ToChar(Raw_Packet); Tag_Value += Tag_Value_Tmp.ToString(); // Tag_Value 는 Dictionary에서 Value값이 될 것이다. } } } Count = 0; } } catch (Exception e) { client.Close(); //My_TimerThread MTT = new My_TimerThread(); timer_GetData.Stop(); LFC.Log("데이터 얻는 행위 중단"); //MTT.timer2Stop(); 20170316 //LFC.Log("연산 타이머 중단"); LFC.Log("통신끊김" + e); LFC.Log("재접속시작" + Convert.ToString(DateTime.Now)); Form1 F1 = new Form1(); while (true) { string ReturnValue = iCos3_Conn(); bool check = false; if (ReturnValue == "SUCCESS" && check == false) { check = true; My_TimerThread.check = false; LFC.Log("접속완료" + Convert.ToString(DateTime.Now)); GetData_From_iCos GFi = new GetData_From_iCos(); GFi.ReadTag(); LFC.Log("관제점 재등록 완료" + Convert.ToString(DateTime.Now)); timer_GetData.Start(); LFC.Log("데이터 얻는 타이머 동작시작 완료" + Convert.ToString(DateTime.Now)); //GetValueTimer(); 20170316 //MTT.timer2start(); break; } } } } } }