You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
11 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
/// <summary>
/// Socket对象
/// </summary>
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
/// <summary>
/// 通讯握手
/// </summary>
/// <param name="Plc_IP"></param>
/// <param name="Tcp_Port"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 写
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
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
}
}