diff --git a/README.md b/README.md index 7952186c..89098468 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,10 @@ Showcase ------------- http://www.cnblogs.com/evilcat/ +教程 +------------- +https://edu.csdn.net/course/detail/30835 + 联系方式 ------------- hijkl1999@yeah.net diff --git a/SCADA/Example/CoreTest.exe b/SCADA/Example/CoreTest.exe index c7cd95c4..5599b167 100644 Binary files a/SCADA/Example/CoreTest.exe and b/SCADA/Example/CoreTest.exe differ diff --git a/SCADA/Program/.vs/DataExchange/v16/.suo b/SCADA/Program/.vs/DataExchange/v16/.suo new file mode 100644 index 00000000..dfddda01 Binary files /dev/null and b/SCADA/Program/.vs/DataExchange/v16/.suo differ diff --git a/SCADA/Program/ClientDriver/ClientDriver.cs b/SCADA/Program/ClientDriver/ClientDriver.cs index f43f9901..f6f607d1 100644 --- a/SCADA/Program/ClientDriver/ClientDriver.cs +++ b/SCADA/Program/ClientDriver/ClientDriver.cs @@ -365,175 +365,216 @@ public void Init() private void ReciveData() { if (!_active || _plcReader.tcpRecive == null) return; - List historys = null; byte[] bytes = new byte[ushort.MaxValue]; - byte[] temp = new byte[_tcpRecive.ReceiveBufferSize]; + byte[] temp = new byte[ushort.MaxValue]; Storage value = Storage.Empty; - int result = 0; int start = 0; SocketError error; + int result = 0; do { - if (!_tcpRecive.Connected) return; - result = _tcpRecive.Receive(bytes, 0, bytes.Length, SocketFlags.None, out error); - if (error == SocketError.Success) + if (!_tcpRecive.Connected || !_active) return; + try { - if (DataChange != null) - historys = new List(); - //DateTime time = DateTime.Now;//当前时间戳 - if (start != 0 && temp[0] == FCTCOMMAND.fctHead) + result = _tcpRecive.Receive(bytes, 0, bytes.Length, SocketFlags.None, out error); + if (error == SocketError.Success) { - int j = 3; - if (start < 0) + List historys = new List(); ; + if (start != 0 && temp[0] == FCTCOMMAND.fctHead) { - Array.Copy(bytes, 0, temp, -start, 5 + start); - } - short tc = BitConverter.ToInt16(temp, j);//总字节数 - if (start < 0) - start += tc; - Array.Copy(bytes, 0, temp, tc - start, start); - j += 2; - while (j < tc) - { - short id = BitConverter.ToInt16(temp, j);//标签ID、数据长度、数据值(T,L,V) + int j = 3; + if (start < 0) + { + Array.Copy(bytes, 0, temp, -start, 5 + start); + } + short tc = BitConverter.ToInt16(temp, j);//总字节数 + if (start < 0) + start += tc; + Array.Copy(bytes, 0, temp, tc - start, start); j += 2; - byte length = temp[j++]; - ITag tag; - if (_items.TryGetValue(id, out tag)) + while (j < tc) { - //数据类型 - switch (tag.Address.VarType) + short id = BitConverter.ToInt16(temp, j);//标签ID、数据长度、数据值(T,L,V) + j += 2; + byte length = temp[j++]; + ITag tag; + if (_items.TryGetValue(id, out tag)) { - case DataType.BOOL: - value.Boolean = BitConverter.ToBoolean(temp, j); - break; - case DataType.BYTE: - value.Byte = temp[j]; - break; - case DataType.WORD: - value.Word = BitConverter.ToUInt16(temp, j);//需测试 - break; - case DataType.SHORT: - value.Int16 = BitConverter.ToInt16(temp, j);//需测试 - break; - case DataType.DWORD: - value.DWord = BitConverter.ToUInt32(temp, j);//需测试 - break; - case DataType.INT: - value.Int32 = BitConverter.ToInt32(temp, j);//需测试 - break; - case DataType.FLOAT: - value.Single = BitConverter.ToSingle(temp, j); - break; - case DataType.STR: - StringTag strTag = tag as StringTag; - if (strTag != null) - { - strTag.String = Encoding.ASCII.GetString(temp, j, length).Trim((char)0); - } - break; - default: - break; + //数据类型 + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(temp, j); + break; + case DataType.BYTE: + value.Byte = temp[j]; + break; + case DataType.WORD: + value.Word = BitConverter.ToUInt16(temp, j);//需测试 + break; + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(temp, j);//需测试 + break; + case DataType.DWORD: + value.DWord = BitConverter.ToUInt32(temp, j);//需测试 + break; + case DataType.INT: + value.Int32 = BitConverter.ToInt32(temp, j);//需测试 + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(temp, j); + break; + case DataType.STR: + StringTag strTag = tag as StringTag; + if (strTag != null) + { + strTag.String = Encoding.ASCII.GetString(temp, j, length).Trim((char)0); + } + break; + default: + break; + } + j += length; + try + { + DateTime time = DateTime.FromFileTime(BitConverter.ToInt64(temp, j)); + //tag.Update(value, time, QUALITIES.QUALITY_GOOD); + //if (historys != null) + historys.Add(new HistoryData(id, QUALITIES.QUALITY_GOOD, value, time)); + } + catch (Exception exp) + { + } + j += 8; } - j += length; - DateTime time = DateTime.FromFileTime(BitConverter.ToInt64(temp, j)); - j += 8; - tag.Update(value, time, QUALITIES.QUALITY_GOOD); - if (historys != null) - historys.Add(new HistoryData(id, QUALITIES.QUALITY_GOOD, value, time)); + else + j += length + 8; } - else - j += length + 8; } - } - byte head = bytes[start]; - int count = start; - while (head == FCTCOMMAND.fctHead && result > count) - { - if (count + 5 > bytes.Length) + byte head = bytes[start]; + int count = start; + while (head == FCTCOMMAND.fctHead && result > count) { - start = count - bytes.Length; - Array.Copy(bytes, count, temp, 0, -start); - break; - } - int j = count + 3; - short tc = BitConverter.ToInt16(bytes, j);//总标签数 - count += tc; - if (count >= bytes.Length) - { - start = count - bytes.Length; - Array.Copy(bytes, count - tc, temp, 0, tc - start); - break; - } - else start = 0; - j += 2; - while (j < count) - { - short id = BitConverter.ToInt16(bytes, j);//标签ID、数据长度、数据值(T,L,V) + if (count + 5 > bytes.Length) + { + start = count - bytes.Length; + Array.Copy(bytes, count, temp, 0, -start); + break; + } + int j = count + 3; + short tc = BitConverter.ToInt16(bytes, j);//总标签数 + count += tc; + if (count >= bytes.Length) + { + start = count - bytes.Length; + Array.Copy(bytes, count - tc, temp, 0, tc - start); + break; + } + else start = 0; j += 2; - byte length = bytes[j++]; - ITag tag; - if (_items.TryGetValue(id, out tag)) + while (j < count) { - //数据类型 - switch (tag.Address.VarType) + short id = BitConverter.ToInt16(bytes, j);//标签ID、数据长度、数据值(T,L,V) + j += 2; + byte length = bytes[j++]; + ITag tag; + if (_items.TryGetValue(id, out tag)) { - case DataType.BOOL: - value.Boolean = BitConverter.ToBoolean(bytes, j); - break; - case DataType.BYTE: - value.Byte = bytes[j]; - break; - case DataType.WORD: - value.Word = BitConverter.ToUInt16(bytes, j);//需测试 - break; - case DataType.SHORT: - value.Int16 = BitConverter.ToInt16(bytes, j);//需测试 - break; - case DataType.DWORD: - value.DWord = BitConverter.ToUInt32(bytes, j);//需测试 - break; - case DataType.INT: - value.Int32 = BitConverter.ToInt32(bytes, j);//需测试 - break; - case DataType.FLOAT: - value.Single = BitConverter.ToSingle(bytes, j); - break; - case DataType.STR: - StringTag strTag = tag as StringTag; - if (strTag != null) - { - strTag.String = Encoding.ASCII.GetString(bytes, j, length).Trim((char)0); - } - break; - default: - break; + //数据类型 + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(bytes, j); + break; + case DataType.BYTE: + value.Byte = bytes[j]; + break; + case DataType.WORD: + value.Word = BitConverter.ToUInt16(bytes, j);//需测试 + break; + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(bytes, j);//需测试 + break; + case DataType.DWORD: + value.DWord = BitConverter.ToUInt32(bytes, j);//需测试 + break; + case DataType.INT: + value.Int32 = BitConverter.ToInt32(bytes, j);//需测试 + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(bytes, j); + break; + case DataType.STR: + StringTag strTag = tag as StringTag; + if (strTag != null) + { + strTag.String = Encoding.ASCII.GetString(bytes, j, length).Trim((char)0); + } + break; + default: + break; + } + j += length; + try + { + DateTime time = DateTime.FromFileTime(BitConverter.ToInt64(bytes, j)); + //tag.Update(value, time, QUALITIES.QUALITY_GOOD); + //if (historys != null) + historys.Add(new HistoryData(id, QUALITIES.QUALITY_GOOD, value, time)); + } + catch (Exception exp) + { + } + j += 8; } - j += length; - DateTime time = DateTime.FromFileTime(BitConverter.ToInt64(bytes, j)); - j += 8; - tag.Update(value, time, QUALITIES.QUALITY_GOOD); - if (historys != null) - historys.Add(new HistoryData(id, QUALITIES.QUALITY_GOOD, value, time)); + else + j += length + 8; } - else - j += length + 8; + head = bytes[count]; } - head = bytes[count]; - } - if (DataChange != null && historys.Count > 0) - DataChange(this, new DataChangeEventArgs(1, historys)); + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.OnRecieve), historys); + //if (DataChange != null && historys.Count > 0) + // DataChange(this, new DataChangeEventArgs(1, historys)); + } + else if (error == SocketError.ConnectionReset || error == SocketError.Interrupted + || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + { + _tcpRecive.Dispose(); + return; + } } - else if (error == SocketError.ConnectionReset || error == SocketError.Interrupted - || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + catch (Exception) { _tcpRecive.Dispose(); - _active = false; return; } } while (result > 0); + try + { + _tcpRecive.Dispose(); + } + catch (Exception) + { + } + } + + private void OnRecieve(object stateInfo) + { + var historys = stateInfo as List; + if (historys == null) return; + if (DataChange != null && historys.Count > 0) + DataChange(this, new DataChangeEventArgs(1, historys)); + for (int i = 0; i < historys.Count; i++) + { + var data = historys[i]; + ITag tag; + if (_items.TryGetValue(data.ID, out tag)) + { + tag.Update(data.Value, data.TimeStamp, data.Quality); + } + } } public void OnUpdate(object stateInfo) diff --git a/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs b/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs index 521595b0..2987c2df 100644 --- a/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs +++ b/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs @@ -1224,7 +1224,7 @@ void OnValueChanged(object sender, ValueChangedEventArgs e) DataHelper.Instance.ExecuteStoredProcedure("AddEventLog", DataHelper.CreateParam("@StartTime", SqlDbType.DateTime, tag.TimeStamp), DataHelper.CreateParam("@Source", SqlDbType.NVarChar, tag.ID.ToString(), 50), - DataHelper.CreateParam("@StartTime", SqlDbType.NVarChar, tag.ToString(), 50)); + DataHelper.CreateParam("@Comment", SqlDbType.NVarChar, tag.ToString(), 50)); } public HistoryData[] BatchRead(DataSource source, bool sync, params ITag[] itemArray) diff --git a/SCADA/Program/DataService/ITag.cs b/SCADA/Program/DataService/ITag.cs index 98174d31..5b7e6170 100644 --- a/SCADA/Program/DataService/ITag.cs +++ b/SCADA/Program/DataService/ITag.cs @@ -211,7 +211,7 @@ public override int Write(object value) temp = Convert.ToBoolean(value); else if (!Boolean.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteBit(_plcAddress, temp); } @@ -280,7 +280,7 @@ public override int Write(object value) temp = Convert.ToByte(value); else if (!Byte.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteBits(_plcAddress, temp); } @@ -349,7 +349,7 @@ public override int Write(object value) temp = Convert.ToInt16(value); else if (!short.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteInt16(_plcAddress, temp); } @@ -418,7 +418,7 @@ public override int Write(object value) temp = Convert.ToUInt16(value); else if (!ushort.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteUInt16(_plcAddress, temp); } @@ -486,7 +486,7 @@ public override int Write(object value) temp = Convert.ToInt32(value); else if (!int.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteInt32(_plcAddress, temp); } @@ -554,7 +554,7 @@ public override int Write(object value) temp = Convert.ToUInt32(value); else if (!uint.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteUInt32(_plcAddress, temp); } @@ -623,7 +623,7 @@ public override int Write(object value) temp = Convert.ToSingle(value); else if (!float.TryParse(str, out temp)) return -1; - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteFloat(_plcAddress, temp); } @@ -699,7 +699,7 @@ public override int Write(object value) { if (value == null) return -1; var str = (value is String) ? (String)value : value.ToString(); - _timeStamp = DateTime.Now; + //_timeStamp = DateTime.Now; return _group.WriteString(_plcAddress, str); } diff --git a/SCADA/dll/DataService.dll b/SCADA/dll/DataService.dll index c78f7d84..c779efc9 100644 Binary files a/SCADA/dll/DataService.dll and b/SCADA/dll/DataService.dll differ