实施UDP通讯......

本文介绍了一种基于UDP协议的通讯实现方式,并详细展示了如何通过编写特定的类来完成参数信息的读取与设置。文章包括了通讯类的设计、模块类的功能实现,以及在页面中的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    public class udpServer
    {
        public static string serverIP = "192.168.1.10";   //服务端IP
        public static int serverPort = 6666;         //服务端端口号
        public static string localIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();       //本机IP
        public udpServer()
        {

        }
        public static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//实例化Socket
        /// <summary>
        /// 发送编号,返回一条相应的记录信息
        /// </summary>
        /// <param name="send_message">发送信息</param>
        /// <param name="strReturn">是否有返回</param>
        /// <returns></returns>
        public byte[] sendMessage(byte[] send_message, bool strReturn)
        {
            IPAddress selfIP = IPAddress.Parse(localIP);
            IPEndPoint selfEP = new IPEndPoint(selfIP, 0);

            IPAddress serIP = IPAddress.Parse(serverIP);
            IPEndPoint serEP = new IPEndPoint(serIP, serverPort);

            int count = 0;
            EndPoint remort = (EndPoint)serEP;//接收从服务端返回的信息

            socket.SendTo(send_message, send_message.Length, SocketFlags.None, serEP);//发送信息
            if (strReturn == false)
            {
                return null;
            }
            byte[] result = new byte[1024];
            byte[] newResult = null;
            try
            {
                for (int i = 0; i < 6; i++)
                {
                    System.Threading.Thread.Sleep(500);
                    if (socket.Available > 0)
                    {
                        count = socket.ReceiveFrom(result, result.Length, SocketFlags.None, ref remort);//接收指令
                        newResult = new byte[count];
                        Array.Copy(result, newResult, count);
                        break;
                    }
                }
                return newResult;
            }
            catch
            {
                return null;
            }
        }

}

==========================================================

根据通讯规约文档,整理各模块的通讯类.注意字节数量.

 

例如:

    public class ParameterInfo
    {
        //读写参数信息

        private UInt16 selfID = 0;
        private UInt16 clientID = 0;

        public ParameterInfo(UInt16 self_id,UInt16 client_id)
        {
            this.selfID = self_id;
            this.clientID = client_id;
        }
        public UInt32 DianLiuBianBi = 0;        //电流变比
        public UInt32 XiangJianBaoHu = 0;       //相间保护
        public double BaoHuYanShi = 0.0;          //保护延时
        public double LingXuBaoHu = 0.0;          //零序保护
        public double LingXuYanShi = 0.0;         //零序延时
        public double DiYaDingZhi = 0.0;          //低压定值
        public double DiYaYanShi = 0.0;           //低压延时
        public UInt32 XiaoZhengCanShuA = 0;     //校正参数A
        public UInt32 XiaoZhengCanShuB = 0;     //校正参数B
        public UInt32 XiaoZhengCanShuC = 0;     //校正参数C
        public UInt32 XiaoZhengCanShu0 = 0;     //校正参数0
        public UInt32 MiMaZhi = 0;              //密码值

        /// <summary>
        /// 保护参数读取
        /// </summary>
        /// <returns></returns>
        public byte[] readParameter()
        {
            //功能码 : 控制器参数读取0X51 ,81
            Int16 type = 81;
            Int32 length = 0;       //信息体长度
            byte[] message = new byte[10];
            int i = 0;

            message[i++] = (byte)selfID;
            message[i++] = (byte)(selfID >> 8);
            message[i++] = (byte)clientID;
            message[i++] = (byte)(clientID >> 8);

            message[i++] = (byte)80;
            message[i++] = (byte)type;
            message[i++] = (byte)length;
            message[i++] = (byte)(length >> 8);

            UInt16 yzNum = hx_fj_mobile.CRC.ModBusCRC16(message, (UInt16)i);
            message[i++] = (byte)yzNum;
            message[i++] = (byte)(yzNum >> 8);

            return message;
        }
        /// <summary>
        /// 解析保护参数
        /// </summary>
        /// <param name="receiveMessage">收到的数据包</param>
        /// <returns>返回布尔值</returns>
        public bool JieXiParameter(byte[] receiveMessage)
        {
            bool flag = false;
            int move = 0;
            UInt32 index = 8;
            //if ((receiveMessage[move++]) + (receiveMessage[move++] << 8) != selfID || (receiveMessage[move++]) + receiveMessage[move++] << 8 != clientID || receiveMessage[move++] != 0x50 || receiveMessage[move++] != 0x5b || (receiveMessage[move++]) + (receiveMessage[move++] << 8) != 25 || !hx_fj_mobile.CRC.ModBus_TstCRC(receiveMessage, (UInt16)(receiveMessage.Length - 2)))
            //{
            //    flag = false;
            //    return flag;
            //}
            int data = 0;
            data = receiveMessage[move++] + (receiveMessage[move++] << 8);
            if (data != clientID)
            {
                flag = false;
                return flag;
            }
            data = receiveMessage[move++] + (receiveMessage[move++] << 8);
            if (data != selfID)
            {
                flag = false;
                return flag;
            }
            data = receiveMessage[move++];
            if (data != 0x50)
            {
                flag = false;
                return flag;
            }
            data = receiveMessage[move++];
            if (data != 0x51)
            {
                flag = false;
                return flag;
            }
            data = (receiveMessage[move++]) + (receiveMessage[move++] << 8);
            if (data != 52)
            {
                flag = false;
                return flag;
            }
            double temp = 0;
            int m1 = receiveMessage[move++];
            int m2 = receiveMessage[move++] << 8;
            int m3 = receiveMessage[move++] << 16;
            int m4 = receiveMessage[move++] << 24;
            temp = m1 + m2 + m3 + m4;//结构体长度
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            DianLiuBianBi =(UInt32) temp;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            XiangJianBaoHu = ((UInt32)temp) /1000;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            BaoHuYanShi = ((double)temp) / 1000;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            LingXuBaoHu = ((double)temp) / 1000;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            LingXuYanShi = ((double)temp) / 1000;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            DiYaDingZhi = ((UInt32)temp) / 10;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            DiYaYanShi = ((double)temp) / 1000;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            XiaoZhengCanShuA = (UInt32)temp;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            XiaoZhengCanShuB =(UInt32) temp;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            XiaoZhengCanShuC =(UInt32) temp;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            XiaoZhengCanShu0 = (UInt32)temp;
            temp = receiveMessage[move++] + (receiveMessage[move++] << 8) + (receiveMessage[move++] << 16) + (receiveMessage[move++] << 24);
            MiMaZhi =(UInt32) temp;
            flag = true;
            return flag;
        }
        /// <summary>
        /// 组合要设置的参数信息
        /// </summary>
        /// <returns></returns>
        public byte[] setParameter()
        {
            Int16 type = 0x52;      //设置参数码
            int length = 52;
            byte[] message = new byte[62];
            int move = 0;
            message[move++] = (byte)selfID;
            message[move++] = (byte)(selfID >> 8);

            message[move++] = (byte)clientID;
            message[move++] = (byte)(clientID >> 8);

            message[move++] = 80;
            message[move++] =(byte) type;

            message[move++] = (byte)length;
            message[move++] = (byte)(length >> 8);

            message[move++] = (byte)52;
            message[move++] = (byte)(52 >> 8);
            message[move++] = (byte)(52 >> 16);
            message[move++] = (byte)(52 >> 24);

            UInt32 temp=DianLiuBianBi;
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = (UInt32)(XiangJianBaoHu * 1000);
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp =(UInt32) (BaoHuYanShi * 1000);
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = (UInt32)(LingXuBaoHu * 1000);
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = (UInt32)(LingXuYanShi * 1000);
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = (UInt32)(DiYaDingZhi * 10);
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = (UInt32)(DiYaYanShi * 1000);
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = XiaoZhengCanShuA;
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = XiaoZhengCanShuB;
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = XiaoZhengCanShuC;
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = XiaoZhengCanShu0;
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            temp = MiMaZhi;
            message[move++] = (byte)temp;
            message[move++] = (byte)(temp >> 8);
            message[move++] = (byte)(temp >> 16);
            message[move++] = (byte)(temp >> 24);

            UInt16 yzNum = hx_fj_mobile.CRC.ModBusCRC16(message, (UInt16)move);
            message[move++] = (byte)yzNum;
            message[move++] = (byte)(yzNum >> 8);
            return message;
        }
    }

================================================

页面相应的调用:

实例化通讯类,实例化模块类,传递相应的参数,在页面中进行调用.

如:

           udpServer udpclass=new udpServer();//通讯类
            udpclass.sendMessage(udpcontrol.palpitant(), false);        // 发送心跳
            try
            {
                ParameterInfo parameter = new ParameterInfo(Convert.ToUInt16(bianliang.userIDADD()), Convert.ToUInt16(BianLian_pub.rtuID));模块类
                byte[] receiveMessage = udpclass.sendMessage(parameter.readParameter(), true);//读取参数信息,服务器返回相应的信息.

判断返回的数据信息,根据规约查看相应的索引值,如果正确,读取参数信息成功,不正确,读取参数信息失败.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值