using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading; namespace Mesnac.Equip.OMRON.FINS { public class TcpFactory { private static TcpFactory _instance = null; //TCP工厂实例 private string _stationPC = "12"; //PC站点 private string _stationPLC = "13"; //PLC站点\ private string _plcIP = string.Empty;//PLCip private string _tcpPort = "";//端口号 private byte client_node_no; private byte server_node_no; private TcpClient plc_Socket = null; private NetworkStream myNetworkStream; private TcpFactory(string stationPC, string stationPLC, string PlcIP, string TcpPort) { this._stationPC = stationPC; this._stationPLC = stationPLC; this._plcIP = PlcIP; this._tcpPort = TcpPort; } public static TcpFactory GetInstance(string stationPC, string stationPLC, string PlcIP, string TcpPort) { return new TcpFactory(stationPC, stationPLC, PlcIP, TcpPort); if (_instance == null) { _instance = new TcpFactory(stationPC, stationPLC, PlcIP, TcpPort); } return _instance; } /// /// Socket对象 /// public TcpClient MainTCPSocket { get { return this.plc_Socket; } } #region 十六进制转换 private byte[] StringToBytes16(string source) { byte[] destination = new byte[source.Length / 2]; for (int i = 0, j = 0; i < source.Length && j < source.Length / 2; i += 2, j++) { string item = source.Substring(i, 2); destination[j] = Convert.ToByte(item, 16); } return destination; } #endregion /// /// 通讯握手 /// /// /// /// public bool creatConn() { bool execResu = true; //创建Socket连接 46494E530000000C000000000000000000000000 string tcp_header = "46494E530000000C000000000000000000000001"; byte[] fins_tcp_header = StringToBytes16(tcp_header); try { plc_Socket = new TcpClient(); plc_Socket.Connect(IPAddress.Parse(_plcIP), int.Parse(_tcpPort)); myNetworkStream = plc_Socket.GetStream(); } catch (SocketException ex) { ICSharpCode.Core.LoggingService.Error("PLC连接失败:" + ex.Message); //MessageBox.Show(ex.Message); execResu = false; return execResu; } WriteData(fins_tcp_header); byte[] responseMessage = ReadData(); //检查返回包 if (responseMessage.Length == 24) { if (responseMessage[8] != 0x00 || responseMessage[9] != 0x00 || responseMessage[10] != 0x00 || responseMessage[11] != 0x01 || responseMessage[12] != 0x00 || responseMessage[13] != 0x00 || responseMessage[14] != 0x00 || responseMessage[15] != 0x00) { return false; } client_node_no = responseMessage[19]; server_node_no = responseMessage[23]; } else { return false; } return execResu; } public bool Read(int block, int start, int len, out object[] buff) { lock (this) { string Ssend_header = "46494E530000001A"; Ssend_header += "0000000200000000"; byte[] send_header = StringToBytes16(Ssend_header); Random ra = new Random(unchecked((int)DateTime.Now.Ticks)); int SID = ra.Next(1, 100);//自动生成数来检查返回包 byte[] fins_header_comm = new byte[12]; fins_header_comm[0] = 0x80;//ICF fins_header_comm[1] = 0x00;//RSV fins_header_comm[2] = 0x02;//GCT fins_header_comm[3] = 0x00; //DNA fins_header_comm[4] = server_node_no;//PLC端节点号 fins_header_comm[5] = 0x00;//DA2 fins_header_comm[6] = 0x00;//SNA fins_header_comm[7] = client_node_no;//PC端节点号,通过连接程序直接获得的 fins_header_comm[8] = 0x00;//SA2 fins_header_comm[9] = Convert.ToByte(SID.ToString(), 16);//SID fins_header_comm[10] = 0x01; fins_header_comm[11] = 0x01;//读命令 string saddr_value = "82" + Convert.ToString(block + start, 16).PadLeft(4, '0') + "00";//821C2000 saddr_value += Convert.ToString(len, 16).PadLeft(4, '0'); byte[] addr_value = StringToBytes16(saddr_value); WriteData(Combin(send_header, fins_header_comm, addr_value)); //WriteData(); //WriteData(); byte[] Reseponse = ReadData(); //MessageBox.Show(Reseponse.Length.ToString()); //检查返回包 buff = new object[len]; if (Reseponse[8] != 0 || Reseponse[9] != 0 || Reseponse[10] != 0 || Reseponse[11] != 2 || Reseponse[12] != 0 || Reseponse[13] != 0 || Reseponse[14] != 0 || Reseponse[15] != 0 || Reseponse[26] != 1 || Reseponse[27] != 1 || Reseponse[28] != 0 || Reseponse[29] != 0 || Reseponse[25] != Convert.ToByte(SID.ToString(), 16)) { return false; } //MessageBox.Show((Convert.ToInt32(Reseponse[Reseponse.Length - 2].ToString("X2") + Reseponse[Reseponse.Length - 1].ToString("X2"), 16)).ToString()); int j = 0; for (int i = len; i > 0; i--) { buff[j] = Convert.ToInt32(Reseponse[Reseponse.Length - (i * 2)].ToString("X2") + Reseponse[Reseponse.Length - i * 2 + 1].ToString("X2")); j++; } return true; } } byte[] Combin(byte[] header, byte[] comm, byte[] value) { int length=header.Length + comm.Length + value.Length; byte[] returnByte = new byte[length]; int j=0; for (int i = 0; i < header.Length; i++) { returnByte[j] = header[i]; j++; } for (int i = 0; i < comm.Length; i++) { returnByte[j] = comm[i]; j++; } for (int i = 0; i < value.Length; i++) { returnByte[j] = value[i]; j++; } return returnByte; } /// /// 写 /// /// /// public bool Write(int block, int start, int[] buff) { int writeCount = 1;//写入数量 string Ssend_header = "46494E53000000"; Ssend_header += Convert.ToString((2 * writeCount + 1 + 25), 16).PadLeft(2, '0'); Ssend_header += "0000000200000000"; byte[] send_header = StringToBytes16(Ssend_header); Random ra = new Random(unchecked((int)DateTime.Now.Ticks)); int SID = ra.Next(1, 100); byte[] fins_header_comm = new byte[12]; fins_header_comm[0] = 0x80;//ICF4294967295 fins_header_comm[1] = 0x00;//RSV fins_header_comm[2] = 0x02;//GCT fins_header_comm[3] = 0x00; //DNA fins_header_comm[4] = server_node_no;//PLC端节点号 fins_header_comm[5] = 0x00;//DA2 fins_header_comm[6] = 0x00;//SNA fins_header_comm[7] = client_node_no;//PC端节点号,通过连接程序直接获得的 fins_header_comm[8] = 0x00;//SA2 fins_header_comm[9] = Convert.ToByte(SID.ToString(), 16);//SID fins_header_comm[10] = 0x01; fins_header_comm[11] = 0x02;//写命令 string saddr_value = "82" + Convert.ToString(block + start, 16).PadLeft(4, '0') + "00"; saddr_value += Convert.ToString(writeCount, 16).PadLeft(4, '0'); for (int i = 0; i < buff.Length; i++) { if ("System.Int64" == buff[i].GetType().ToString()) { saddr_value += Convert.ToString((long)buff[i], 16).PadLeft(8, '0').Substring(4, 4); saddr_value += Convert.ToString((long)buff[i], 16).PadLeft(8, '0').Substring(0, 4); } else { saddr_value += Convert.ToString((int)buff[i], 16).PadLeft(4, '0'); } } byte[] addr_value = StringToBytes16(saddr_value); WriteData(send_header); WriteData(fins_header_comm); WriteData(addr_value); byte[] Reseponse = ReadData(); //检查返回包 if (Reseponse[8] != 0 || Reseponse[9] != 0 || Reseponse[10] != 0 || Reseponse[11] != 2 || Reseponse[12] != 0 || Reseponse[13] != 0 || Reseponse[14] != 0 || Reseponse[15] != 0 || Reseponse[26] != 1 || Reseponse[27] != 2 || Reseponse[28] != 0 || Reseponse[29] != 0 || Reseponse[25] != Convert.ToByte(SID.ToString(), 16)) { ICSharpCode.Core.LoggingService.Error("PLC连接失败:" + Reseponse[8].ToString() + Reseponse[9].ToString() + Reseponse[10].ToString() + Reseponse[11].ToString()); //MessageBox.Show(Reseponse[8].ToString() + Reseponse[9].ToString() + Reseponse[10].ToString() + Reseponse[11].ToString()); return false; } return true; } #region 数据处理 private void WriteData(byte[] myByte) { byte[] writeBytes = myByte; myNetworkStream.Write(writeBytes, 0, writeBytes.Length); myNetworkStream.Flush(); Thread.Sleep(10); } private byte[] ReadData() { int k = plc_Socket.Available; while (k == 0) { k = plc_Socket.Available; Thread.Sleep(10); } byte[] myBufferBytes = new byte[k]; myNetworkStream.Read(myBufferBytes, 0, k); myNetworkStream.Flush(); return myBufferBytes; } #endregion } }