基本信息
源码名称:C# OPC通信客户端(S7-1200 Control)
源码大小:0.16M
文件格式:.rar
开发语言:C#
更新时间:2018-02-10
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 3 元 
   源码介绍
OPC客户端实现与服务器的通信,收发数据,同步异步通信,S7-1200 Control with OPC


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OPCAutomation;

namespace S7_1200_Control_with_OPC
{
    public partial class Form1 : Form
    {
        //public enum MyOPCType : ushort
        //{
        //    _byte = 0,
        //    _short = 1,
        //    _bool = 2,
        //    _string = 3,
        //    _string2 = 4,
        //};
        //OPCType mytype;
        public struct aItem
        {
            public string NameForOPC;
            //public MyOPCType opc_type;
            public object Value;
            public bool Writeable;
            public string Descrip;
            public string Timestamps;
            public string Quality;

            public int itmHandleClient;
            public int itmHandleServer;
        }
        aItem[] Data_Array;
        aItem[] Data_Array2;

        public Form1()
        {
            InitializeComponent();
        }

        #region 私有变量
        OPCServer MyServer;
        OPCGroups MyGroups;

        OPCGroup MyGroup;
        OPCGroup MyGroup2;

        OPCItems MyItems;
        OPCItems MyItems2;

        OPCItem[] MyItem;
        OPCItem[] MyItem2;
        #endregion
        string strHostIP = "";
        string strHostName = "";

        private void Form1_Load(object sender, EventArgs e)
        {
            GetLocalServer();
            Data_Array = new aItem[5];

            Data_Array[0].NameForOPC = "A0000";
            Data_Array[0].Value = 0;
            //Data_Array[0].opc_type = MyOPCType._byte;
            Data_Array[0].itmHandleClient = 0;
            Data_Array[0].Writeable = false;


            Data_Array[1].NameForOPC = "A0001";
            Data_Array[1].Value = 0;
            //Data_Array[1].opc_type = MyOPCType._short;
            Data_Array[1].itmHandleClient = 1;
            Data_Array[1].Writeable = false;

            Data_Array[2].NameForOPC = "A0002";
            Data_Array[2].Value = false;
            //Data_Array[2].opc_type = MyOPCType._bool;
            Data_Array[2].itmHandleClient = 2;
            Data_Array[2].Writeable = false;

            Data_Array[3].NameForOPC = "B001";
            Data_Array[3].Value = "";
            //Data_Array[3].opc_type = MyOPCType._string;
            Data_Array[3].itmHandleClient = 3;
            Data_Array[3].Writeable = false;

            Data_Array[4].NameForOPC = "B002";
            Data_Array[4].Value = "";
            //Data_Array[4].opc_type = MyOPCType._string2;
            Data_Array[4].itmHandleClient = 4;
            Data_Array[4].Writeable = false;

            Data_Array2 = new aItem[4];

            Data_Array2[0].NameForOPC = "B001";
            Data_Array2[0].Value = "";
            //Data_Array2[0].opc_type = MyOPCType._string;
            Data_Array2[0].itmHandleClient = 3;
            Data_Array2[0].Writeable = false;

            Data_Array2[1].NameForOPC = "B002";
            Data_Array2[1].Value = "";
            //Data_Array2[1].opc_type = MyOPCType._string;
            Data_Array2[1].itmHandleClient = 0;
            Data_Array2[1].Writeable = false;

            Data_Array2[2].NameForOPC = "W01";
            Data_Array2[2].Value = "";
            //Data_Array2[2].opc_type = MyOPCType._string;
            Data_Array2[2].itmHandleClient = 1;
            Data_Array2[2].Writeable = true;

            Data_Array2[3].NameForOPC = "W02";
            Data_Array2[3].Value = "";
            //Data_Array2[3].opc_type = MyOPCType._string;
            Data_Array2[3].itmHandleClient = 2;
            Data_Array2[3].Writeable = true;
        }
        private void GetLocalServer()
        {
            strHostName = System.Net.Dns.GetHostName();
            System.Net.IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(strHostName);
            for (int i = 0; i < ipEntry.AddressList.Length; i  )
            {
                if (ipEntry.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    strHostIP = ipEntry.AddressList[i].ToString();
                    break;
                }
            }

            try
            {
                MyServer = new OPCServer();
                object serverList = MyServer.GetOPCServers(strHostName);

                foreach (string alist in (Array)serverList)
                {
                    comboBox_ServerNames.Items.Add(alist);
                }
                if (comboBox_ServerNames.Items.Count >= 1)
                {
                    comboBox_ServerNames.SelectedIndex = 0;
                }
                textBox_IP.Text = strHostIP;
            }
            catch (Exception err)
            {
                throw new Exception("GetLoaclServer :"   err.Message);
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {

                //MyServer.Connect(comboBox_ServerNames.SelectedItem.ToString(), strHostIP);
                MyServer.Connect(comboBox_ServerNames.SelectedItem.ToString(), "");  //连接本机,后面的IP就不需要了

                if (MyServer.ServerState == (int)OPCServerState.OPCRunning)         //判断是否连接上了
                {
                    CreateGroup();
                }
                else
                {
                    throw new Exception("ServerState: "   MyServer.ServerState);
                }

                MyServer.ServerShutDown  = ServerShutDown;//服务器断开事件,没有发现他在哪里用的。

            }
            catch (Exception err)
            {
                MessageBox.Show("ConnectServer:"   err.Message);
            }
        }

        private bool CreateGroup()
        {
            try
            {
                MyGroups = MyServer.OPCGroups;
                MyGroup = MyServer.OPCGroups.Add("Group1");
                MyGroup2 = MyServer.OPCGroups.Add("Group2");
                OPCGroup Mygroup3 = MyGroups.Add("Test3");      //待删除的组
                //以下设置属性
                {
                    MyGroups.DefaultGroupIsActive = true;      //激活组
                    MyGroups.DefaultGroupDeadband = 0;         //死区值,设为0时,服务器端该组内任何数据变化都通知组
                    MyGroups.DefaultGroupUpdateRate = 200;     //默认组群的刷新频率为200ms

                    MyGroup.UpdateRate = 100;           //刷新频率为1秒
                    MyGroup.IsSubscribed = true;        //使用订阅功能,即可以异步,默认为false。
                                                        //如果没有订阅,则该组的DataChange回调事件不会发生
                    MyGroup2.UpdateRate = 100;
                    MyGroup2.IsSubscribed = true;
                }
                MyGroup.DataChange  = new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange);

                MyGroup2.DataChange  = new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange2);
                MyGroup2.AsyncWriteComplete  = new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(GroupAsyncWriteComplete);
                MyGroup2.AsyncReadComplete  = new DIOPCGroupEvent_AsyncReadCompleteEventHandler(GroupAsyncReadComplete);

                MyServer.OPCGroups.Remove("Test3");//移除组
                //添加Item
                AddGroupItems();  //设置组内的Items
            }
            catch (Exception err)
            {
                throw new Exception("CreateGroup:"   err.Message);
            }
            return true;
        }

        private void AddGroupItems()
        {
            #region Important clue
            //没有搞懂以下的意义。经测试,感觉不是这样的,如果有好几个string,clienthandle都是3的话,那订阅的
            //DataChange事件在触发的时候clienthandle都是一样的,这样不知道如何分辨是哪一个Item的值了。所以我用的
            //都是比3要大的值。

            //MyItem2[0] = MyItems2.AddItem("BPJ.Db1.dbb96", 0);//byte
            //MyItem2[1] = MyItems2.AddItem("BPJ.Db1.dbw10", 1);//short
            //MyItem2[2] = MyItems2.AddItem("BPJ.Db16.dbx0", 2);//bool
            //MyItem2[3] = MyItems2.AddItem("BPJ.Db11.S0", 3);//string
            #endregion

            MyItems = MyGroup.OPCItems;
            MyItems2 = MyGroup2.OPCItems;

            MyItem = new OPCItem[Data_Array.Length];
            MyItem2 = new OPCItem[Data_Array2.Length];

            for (int i = 0; i < Data_Array.Length; i  )
            {
                //MyItem[i] = MyItems.AddItem(Data_Array[i].NameForOPC, (int)(Data_Array[i].opc_type));
                MyItem[i] = MyItems.AddItem(Data_Array[i].NameForOPC, Data_Array[i].itmHandleClient);
            }

            for (int i = 0; i < Data_Array2.Length; i  )
            {
                //MyItem2[i] = MyItems2.AddItem(Data_Array2[i].NameForOPC, (int)(Data_Array2[i].opc_type));
                MyItem2[i] = MyItems2.AddItem(Data_Array2[i].NameForOPC, Data_Array2[i].itmHandleClient);
            }
            //移除组内Item的方法
            //Array Errors;
            //int[] temp = new int[] { 0, MyItem[3].ServerHandle };
            //Array serverHandle = (Array)temp;
            //MyItems.Remove(1, ref serverHandle, out Errors);
            //MyItem[3] = MyItems.AddItem("BPJ.Db11.S0", 3);//string

        }

        public void ServerShutDown(string Reason)//服务器先行断开
        {
            MyServer.OPCGroups.RemoveAll();
            MyServer.Disconnect();
        }

        void GroupDataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            bool UpdateFlg = false;
            int UpdateNum = -1;
            for (int i = 1; i <= NumItems; i  )
            {
                for (int j = 0; j < Data_Array.Length; j  )
                {
                    //if (Data_Array[j].itmHandleClient == Convert.ToInt32(ClientHandles.GetValue(i)))
                    if (Data_Array[j].itmHandleClient == Convert.ToInt32(ClientHandles.GetValue(i)))
                    {
                        Data_Array[j].Value = ItemValues.GetValue(i).ToString();
                        Data_Array[j].Quality = Qualities.GetValue(i).ToString();
                        Data_Array[j].Timestamps = TimeStamps.GetValue(i).ToString();

                        UpdateFlg = true;
                        UpdateNum = j;
                        break;
                    }
                }
                if (UpdateFlg == true)
                {
                    switch (UpdateNum)
                    {
                        case 0:
                            this.textBoxA0.Text = Data_Array[0].Value.ToString();
                            break;
                        case 1:
                            this.textBoxA1.Text = Data_Array[1].Value.ToString();
                            break;
                        case 2:
                            this.textBoxA2.Text = Data_Array[2].Value.ToString();
                            break;
                        case 3:
                            this.textBoxB1.Text = Data_Array[3].Value.ToString();
                            break;
                        case 4:
                            this.textBoxB2.Text = Data_Array[4].Value.ToString();
                            break;
                    }
                    UpdateFlg = false;
                }

            }
        }

        void GroupDataChange2(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {

            for (int i = 1; i <= NumItems; i  )
            {
                for (int j = 0; j < Data_Array2.Length; j  )
                {
                    if (Data_Array2[j].itmHandleClient == Convert.ToInt32(ClientHandles.GetValue(i)))
                    {
                        Data_Array2[j].Value = ItemValues.GetValue(i).ToString();
                        Data_Array2[j].Quality = Qualities.GetValue(i).ToString();
                        Data_Array2[j].Timestamps = TimeStamps.GetValue(i).ToString();

                        break;
                    }
                }

            }
        }

        void GroupAsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
        {
            labelSysWrite.Text = "异步写完成。NumItems:"   NumItems.ToString()   "\r\n时间:"   DateTime.Now.ToString();
        }

        void GroupAsyncReadComplete(int TransactionID, int NumItems, ref System.Array ClientHandles, ref System.Array ItemValues, ref System.Array Qualities, ref System.Array TimeStamps, ref System.Array Errors)
        {
            bool UpdateFlg = false;
            int UpdateNum = -1;
            for (int i = 1; i <= NumItems; i  )
            {
                for (int j = 0; j < Data_Array2.Length; j  )
                {
                    if (Data_Array2[j].itmHandleClient == Convert.ToInt32(ClientHandles.GetValue(i)))
                    {
                        Data_Array2[j].Value = ItemValues.GetValue(i).ToString();
                        Data_Array2[j].Quality = Qualities.GetValue(i).ToString();
                        Data_Array2[j].Timestamps = TimeStamps.GetValue(i).ToString();
                        UpdateFlg = true;
                        UpdateNum = j;
                        break;
                    }
                }
                if (UpdateFlg)
                {
                    switch (UpdateNum)
                    {
                        case 0:
                            this.textBoxB1_2.Text = ItemValues.GetValue(i).ToString();
                            break;
                        case 1:
                            this.textBoxB2_2.Text = ItemValues.GetValue(i).ToString();
                            break;
                        default:
                            break;
                    }
                    UpdateFlg = false;
                }
            }
            labelSysRead.Text = "异步读完成。NumItems:"   NumItems.ToString()   "\r\n时间:"   DateTime.Now.ToString();
        }

        private void btnSysRead_Click(object sender, EventArgs e)
        {
            //同步读
            object ItemValues, Qualities, TimeStamps;

            MyItem2[0].Read(1, out ItemValues, out Qualities, out TimeStamps);
            this.textBoxB1_2.Text = Convert.ToString(ItemValues);

            MyItem2[1].Read(1, out ItemValues, out Qualities, out TimeStamps);
            this.textBoxB2_2.Text = Convert.ToString(ItemValues);
        }

        private void btnASysRead_Click(object sender, EventArgs e)
        {
            //异步读,会在事件中给出读的值
            int[] tmp = new int[] { 0, MyItem2[0].ServerHandle, MyItem2[1].ServerHandle };
            Array serverHandles = (Array)tmp;
            Array Errors;
            int cancelID;
            MyGroup2.AsyncRead(2, ref serverHandles, out Errors, 1, out cancelID);

            //经测试,也可以读出数据。有的时候会有些延迟
            //this.textBoxB1_2.Text = MyItem2[0].Value;
            //this.textBoxB2_2.Text = MyItem2[1].Value;
        }

        private void btnSysWrite_Click(object sender, EventArgs e)
        {
            //同步写
            MyItem2[2].Write(textBoxW1_2.Text);
            MyItem2[3].Write(textBoxW2_2.Text);

            this.textBoxW1_2.Text = "";
            this.textBoxW2_2.Text = "";
        }

        private void btnASysWrite_Click(object sender, EventArgs e)
        {
            //异步写
            //异步写时,Array数组从下标1开始而非0!
            int[] tmp = new int[] { 0, MyItem2[2].ServerHandle, MyItem2[3].ServerHandle };
            Array serverHandles = (Array)tmp;
            object[] valueTemp = new object[3] { "", textBoxW1_2.Text, textBoxW2_2.Text };
            Array values = (Array)valueTemp;
            Array Errors;
            int cancelID;
            MyGroup2.AsyncWrite(2, ref serverHandles, ref values, out Errors, 1, out cancelID);

            this.textBoxW1_2.Text = "";
            this.textBoxW2_2.Text = "";
        }

        private void btnSysRead2_Click(object sender, EventArgs e)
        {
            //同步读
            object ItemValues, Qualities, TimeStamps;

            MyItem2[2].Read(1, out ItemValues, out Qualities, out TimeStamps);
            this.textBoxW1_2.Text = Convert.ToString(ItemValues);

            MyItem2[3].Read(1, out ItemValues, out Qualities, out TimeStamps);
            this.textBoxW2_2.Text = Convert.ToString(ItemValues);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //善后,关闭之前的工作。
            if (MyGroup != null)
            {
                MyGroup.DataChange  = new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange);
            }

            if (MyGroup2 != null)
            {
                MyGroup2.DataChange  = new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange2);
                MyGroup2.AsyncWriteComplete  = new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(GroupAsyncWriteComplete);
                MyGroup2.AsyncReadComplete  = new DIOPCGroupEvent_AsyncReadCompleteEventHandler(GroupAsyncReadComplete);
            }
            if (MyServer != null)
            {
                //MyServer.OPCGroups.RemoveAll();
                MyServer.Disconnect();
            }
        }
    }
}