/// <summary> /// 向PLC写入数据,数据格式为原始的字节类型 /// </summary> /// <param name="type">写入的数据类型</param> /// <param name="address">初始地址</param> /// <param name="data">原始的字节数据</param> /// <returns>结果</returns> public OperateResultBytes WriteIntoPLC(MelsecDataType type, ushort address, byte[] data) { OperateResultBytes result = new OperateResultBytes(); byte[] _PLCCommand = GetWriteCommand(type, address, data); Array.Copy(data, 0, _PLCCommand, 21, data.Length); //测试指令数据 //string test = ByteToHexString(_PLCCommand); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); HslTimeOut timeout = new HslTimeOut() { WorkSocket = socket }; try { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout); socket.Connect(new IPEndPoint(PLCIpAddress, PortWrite)); timeout.IsSuccessful = true; } catch { result.Message = StringResources.ConnectedFailed; socket.Close(); return(result); } byte[] DataHead = null; try { socket.Send(_PLCCommand); //先接收满9个数据 int NeedReceived = 9; DataHead = NetSupport.ReadBytesFromSocket(socket, NeedReceived); NeedReceived = BitConverter.ToUInt16(DataHead, 7); DataHead = NetSupport.ReadBytesFromSocket(socket, NeedReceived); result.ErrorCode = BitConverter.ToUInt16(DataHead, 0); result.IsSuccess = true; } catch (Exception ex) { result.Message = StringResources.SocketIOException + ex.Message; Thread.Sleep(10); socket.Close(); return(result); } socket.Shutdown(SocketShutdown.Both); Thread.Sleep(10); socket.Close(); socket = null; if (result.ErrorCode > 0) { result.IsSuccess = false; } return(result); }
/// <summary> /// 需要发送的底层数据 /// </summary> /// <param name="headcode">数据的指令头</param> /// <param name="customer">用户的指令头</param> /// <param name="send">需要发送的底层数据</param> /// <param name="sendStatus">发送状态的进度报告,用于显示上传进度</param> /// <param name="receiveStatus">接收状态的进度报告,用于显示下载进度</param> /// <returns></returns> private OperateResultBytes ReadFromServerBase( int headcode, int customer, byte[] send, Action <long, long> sendStatus = null, Action <long, long> receiveStatus = null) { var result = new OperateResultBytes(); // 创建并连接套接字 if (!CreateSocketAndConnect(out Socket socket, IP_END_POINT, result)) { return(result); } // 发送并检查数据是否发送完成 if (!SendBaseAndCheckReceive(socket, headcode, customer, send, result, sendStatus)) { return(result); } // 接收头数据和内容数据 if (!ReceiveAndCheckBytes(socket, out byte[] head, out byte[] content, result, receiveStatus))
private void MenuItem开发中心_Click(object sender, RoutedEventArgs e) { using (FormSuper fs = new FormSuper(() => { OperateResultBytes result = UserClient.Net_simplify_client.ReadFromServer(CommonHeadCode.SimplifyHeadCode.性能计数, new byte[0]); //解析 if (result.IsSuccess) { int[] data = new int[result.Content.Length / 4]; for (int i = 0; i < data.Length; i++) { data[i] = BitConverter.ToInt32(result.Content, i * 4); } return(data); } else { return(null); } })) { fs.ShowDialog(); } }
/// <summary> /// 从三菱PLC中读取想要的数据,返回读取结果 /// </summary> /// <param name="type">想要读取的数据类型</param> /// <param name="address">读取数据的起始地址</param> /// <param name="length">读取的数据长度,字最大值960,位最大值7168</param> /// <returns>带数据头的字节数组</returns> public OperateResultBytes ReadFromPLC(MelsecDataType type, ushort address, ushort length) { OperateResultBytes result = new OperateResultBytes(); //获取指令 byte[] _PLCCommand = GetReadCommand(type, address, length); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); HslTimeOut timeout = new HslTimeOut() { WorkSocket = socket }; try { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout); socket.Connect(new IPEndPoint(PLCIpAddress, GetPort())); timeout.IsSuccessful = true; } catch { ChangePort(); result.Message = StringResources.ConnectedFailed;; socket.Close(); return(result); } byte[] DataHead = null; try { socket.Send(_PLCCommand); //先接收满9个数据 int NeedReceived = 9; DataHead = NetSupport.ReadBytesFromSocket(socket, NeedReceived); NeedReceived = BitConverter.ToUInt16(DataHead, 7); DataHead = NetSupport.ReadBytesFromSocket(socket, NeedReceived); //获取读取代码 result.ErrorCode = BitConverter.ToUInt16(DataHead, 0); result.Content = new byte[DataHead.Length - 2]; Array.Copy(DataHead, 2, result.Content, 0, DataHead.Length - 2); if (type.DataType == 1) { result.Content = ReceiveBytesTranslate(result.Content); } result.IsSuccess = true; } catch (Exception ex) { result.Message = StringResources.SocketIOException + ex.Message; socket.Close(); return(result); } socket.Shutdown(SocketShutdown.Both); socket.Close(); socket = null; if (result.ErrorCode > 0) { result.IsSuccess = false; } return(result); }
/// <summary> /// 从西门子PLC中读取想要的数据,返回结果类说明 /// </summary> /// <param name="type">想要读取的数据类型</param> /// <param name="address">读取数据的起始地址</param> /// <param name="lengh">读取的数据长度</param> /// <returns>返回读取结果</returns> public OperateResultBytes ReadFromPLC(SiemensDataType type, ushort address, ushort lengh) { OperateResultBytes result = new OperateResultBytes(); byte[] _PLCCommand = new byte[16]; _PLCCommand[0] = 0x53; _PLCCommand[1] = 0x35; _PLCCommand[2] = 0x10; _PLCCommand[3] = 0x01; _PLCCommand[4] = 0x03; _PLCCommand[5] = 0x05; _PLCCommand[6] = 0x03; _PLCCommand[7] = 0x08; //指定数据区 _PLCCommand[8] = type.DataCode; _PLCCommand[9] = 0x00; //指定数据地址 _PLCCommand[10] = (byte)(address / 256); _PLCCommand[11] = (byte)(address % 256); //指定数据长度 _PLCCommand[12] = (byte)(lengh / 256); _PLCCommand[13] = (byte)(lengh % 256); _PLCCommand[14] = 0xff; _PLCCommand[15] = 0x02; //超时验证的线程池技术 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); HslTimeOut timeout = new HslTimeOut() { WorkSocket = socket }; try { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout); socket.Connect(new IPEndPoint(PLCIpAddress, GetPort())); timeout.IsSuccessful = true; } catch { ChangePort(); result.Message = StringResources.ConnectedFailed; Thread.Sleep(10); socket?.Close(); return(result); } try { //连接成功,发送数据 socket.Send(_PLCCommand); byte[] rec_head = NetSupport.ReadBytesFromSocket(socket, 16); if (rec_head[8] != 0x00) { result.ErrorCode = rec_head[8]; Thread.Sleep(10); socket?.Close(); return(result); } result.Content = NetSupport.ReadBytesFromSocket(socket, lengh); result.IsSuccess = true; } catch (Exception ex) { result.Message = StringResources.SocketIOException + ex.Message; Thread.Sleep(10); socket?.Close(); return(result); } Thread.Sleep(10); socket?.Close(); //所有的数据接收完成,进行返回 return(result); }
/// <summary> /// 向PLC中写入数据,返回值说明 /// </summary> /// <param name="type">要写入的数据类型</param> /// <param name="address">要写入的数据地址</param> /// <param name="data">要写入的实际数据</param> /// <exception cref="ArgumentNullException">写入的数据不能为空</exception> /// <returns>返回写入结果</returns> public OperateResultBytes WriteIntoPLC(SiemensDataType type, ushort address, byte[] data) { var result = new OperateResultBytes(); byte[] _PLCCommand = new byte[16 + data.Length]; _PLCCommand[0] = 0x53; _PLCCommand[1] = 0x35; _PLCCommand[2] = 0x10; _PLCCommand[3] = 0x01; _PLCCommand[4] = 0x03; _PLCCommand[5] = 0x03; _PLCCommand[6] = 0x03; _PLCCommand[7] = 0x08; //指定数据区 _PLCCommand[8] = type.DataCode; _PLCCommand[9] = 0x00; //指定数据地址 _PLCCommand[10] = (byte)(address / 256); _PLCCommand[11] = (byte)(address % 256); //指定数据长度 _PLCCommand[12] = (byte)(data.Length / 256); _PLCCommand[13] = (byte)(data.Length % 256); _PLCCommand[14] = 0xff; _PLCCommand[15] = 0x02; //放置数据 Array.Copy(data, 0, _PLCCommand, 16, data.Length); //超时验证的线程池技术 var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); var timeout = new HslTimeOut() { WorkSocket = socket }; try { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckConnect), timeout); socket.Connect(new IPEndPoint(PLCIpAddress, PortWrite)); timeout.IsSuccessful = true; } catch { result.Message = StringResources.ConnectedFailed; Thread.Sleep(10); socket?.Close(); return(result); } try { //连接成功,发送数据 socket.Send(_PLCCommand); byte[] rec_head = NetSupport.ReadBytesFromSocket(socket, 16); //分析数据 if (rec_head[8] != 0x00) { result.ErrorCode = rec_head[8]; Thread.Sleep(10); socket?.Close(); return(result); } socket.Shutdown(SocketShutdown.Both); socket.Close(); result.IsSuccess = true; result.Message = "写入成功"; } catch (Exception ex) { result.Message = StringResources.SocketIOException + ex.Message; Thread.Sleep(10); socket?.Close(); return(result); } return(result); }