UDP协议包校验和小工具设计与实现

UDP协议包校验和小工具设计与实现

原代码文件链接:

实现的功能:

C sharp实现界面的设计,UDP校验和的计算,UDP数据包的生成与发送,数据的保存。总体的代码在主页,有兴趣的可以一起学习交流。

存在问题:

界面的设计比较的简单,图标没进行更换,数据的保存是覆盖性的,追加性数据保存会更好些。UDP数据的接收端并不是自己写的,而是通过网络小助手进行的数据接收。

校验和

  校验和的计算方法大同小异,基本的方法都是对应字段二进制反码累加和进行相加。当然了在计算校验和时,二进制相加会出现溢出所以要做溢出处理。
  UDP的校验和主要由:UDP首部,伪首部,数据三个部分组成,UDP检验和的计算需要通过将三部分的相应字段转换成二进制反码相加求和。
  (1)伪首部:源IP地址,目的IP地址,协议填充字段,协议,UDP数据部分。
  (2)首部: 源端口,目的端口,UDP数据部分,检验和。
  (3)数据:UDP最小的长度为8bit

源代码:

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;

namespace UDP_Protocol_design
{
    public partial class Form1 : Form
    {
        string[] udphead = new string[14];
        string allSum;
  
        public Form1()                                                    //窗体的组件随界面的大小缩放
        {
            InitializeComponent(); 
        }
        private float X, Y;                                               //获得控件的长度、宽度、位置、字体大小的数据  

        private void SetTag(Control cons)                                 //Control类,定义控件的基类
        { 
        foreach (Control con in cons.Controls)                            //获取或设置包含有关控件的数据的对象
        {                                       
            con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size; 

            if (con.Controls.Count > 0)
                 SetTag(con);                                             //递归算法
        }
    }                                                                     //实现控件以及字体的缩放      
        private void SetControls(float newx, float newy, Control cons) 
        {
            foreach (Control con in cons.Controls)
            {
                string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
                float a = Convert.ToSingle(mytag[0]) * newx;
                con.Width = (int)a;
                a = Convert.ToSingle(mytag[1]) * newy;
                con.Height = (int)(a);
                a = Convert.ToSingle(mytag[2]) * newx;
                con.Left = (int)(a);
                a = Convert.ToSingle(mytag[3]) * newy;
                con.Top = (int)(a);
                Single currentSize = Convert.ToSingle(mytag[4]) * newy;
                con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                if (con.Controls.Count > 0)
                {
                    SetControls(newx, newy, con);                        //递归
                }
            }
        }
        private void MyForm_Resize(object sender, EventArgs e)
        {
            float newx = (this.Width) / X;                               //当前宽度与变化前宽度之比
            float newy = this.Height / Y;                                //当前高度与变化前宽度之
            SetControls(newx, newy, this);                                   
            this.Text = ("UDP协议包自动生工具设计");                     //显示窗体的标签
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.Resize += new EventHandler(MyForm_Resize);
            X = this.Width;
            Y = this.Height;
            SetTag(this);
    }                                                                     //窗体的组件随界面的而缩放
        private void Label1_Click(object sender, EventArgs e)
        {

        }
        private void Button1_Click(object sender, EventArgs e)           //校验和的入口函数
        {
            if (!InfoCheck())
            {
                return;
            }
            udphead[9] = "0000";
            CacuSum(udphead[0], 1);
            string overflow = "";
            if (allSum.Length > 4)                                       //溢出处理
            {
                for (int i = 0; i < allSum.Length - 4; i++)
                {
                    overflow += allSum[i];
                }
            }
            allSum = allSum.Remove(0, allSum.Length - 4);
            string checksum2 = ConvertHexToBin(TwoSum(overflow, allSum));
            string cumsum = Cumulativesum(TwoSum(overflow, allSum));
            textBox14.Text = checksum2;                                
            textBox13.Text = cumsum;
        }
        private bool InfoCheck()                                         
        {
            DialogResult result;
            string Source = textBox4.Text;                               //源IP地址
            string Destination = textBox5.Text;                          //目的IP地址                                    
                                                      
            if (!IsIP(Source) || !IsIP(Destination))                     //判断输入的IP是否合法
            {
                MessageBoxButtons buttons = MessageBoxButtons.OK;
                string message = "ip地址不合法";
                string caption = "提示";
                result =MessageBox.Show(this, message, caption, buttons); 
                return false;
            }
            string Protocol_fill, Protocol_udp;                         //协议的字段填充值的定义
            string data1, data2, data3, data4, data5, data6, data7, data8;
            try
            {                                                           //UDP伪首部部分
                Protocol_fill = Convert.ToString(Convert.ToInt32(textBox6.Text), 16).PadLeft(2, '0');
                Protocol_udp = Convert.ToString(Convert.ToInt32(textBox22.Text), 16).PadLeft(2, '0');
                udphead[4] = Protocol_fill + Protocol_udp;
                udphead[5] = Convert.ToString(Convert.ToInt32(textBox8. Text), 16).PadLeft(4, '0');
                udphead[6] = Convert.ToString(Convert.ToInt32(textBox9. Text), 16).PadLeft(4, '0');
                udphead[7] = Convert.ToString(Convert.ToInt32(textBox10.Text), 16).PadLeft(4, '0');
                udphead[8] = Convert.ToString(Convert.ToInt32(textBox11.Text), 16).PadLeft(4, '0');
                //udphead[9] = Convert.ToString(Convert.ToInt32(textBox12.Text), 16).PadLeft(4, '0');

                                                                       //UDP数据部分
                data1 = textBox1.Text;
                data2 = textBox7.Text;
                data3 = textBox16.Text;
                data4 = textBox17.Text;
                data5 = textBox21.Text;
                data6 = textBox20.Text;
                data7 = textBox19.Text;
                data8 = textBox18.Text;
                                                                       //UDP部分的进制转化获取数据转换为十六进制
                //data1 = Convert.ToString(Convert.ToInt32(textBox1. Text), 16).PadLeft(2, '0');
                //data2 = Convert.ToString(Convert.ToInt32(textBox7. Text), 16).PadLeft(2, '0');
                //data3 = Convert.ToString(Convert.ToInt32(textBox16.Text), 16).PadLeft(2, '0');
                //data4 = Convert.ToString(Convert.ToInt32(textBox17.Text), 16).PadLeft(2, '0');
                //data5 = Convert.ToString(Convert.ToInt32(textBox21.Text), 16).PadLeft(2, '0');
                //data6 = Convert.ToString(Convert.ToInt32(textBox20.Text), 16).PadLeft(2, '0');
                //data7 = Convert.ToString(Convert.ToInt32(textBox19.Text), 16).PadLeft(2, '0');
                //data8 = Convert.ToString(Convert.ToInt32(textBox18.Text), 16).PadLeft(2, '0');

                udphead[10] = data1+data2;
                udphead[11] = data3+data4;
                udphead[12] = data5+data6;
                udphead[13] = data7+data8;

            }
            catch (Exception)
            {             
                string message = "输入不合法";
                string caption = "提示";
                result = MessageBox.Show(this, message, caption, MessageBoxButtons.OK);
                return false;
            }
            string[] udpSource = Source.Split('.');
            string[] udpDestination = Destination.Split('.');
            for (int i = 0; i < 4; i++)                                  //十进制转十六进制
            {
                udpSource[i] = Convert.ToString(Convert.ToInt32(udpSource[i]), 16).PadLeft(2, '0');           
            }
            for (int i = 0; i < 4; i++)                                  //十进制转十六进制
            {
                udpDestination[i] = Convert.ToString(Convert.ToInt32(udpDestination[i]), 16).PadLeft(2, '0'); 
            }
            udphead[0] = udpSource[0] + udpSource[1];                    //UDP源IP地址
            udphead[1] = udpSource[2] + udpSource[3];
            udphead[2] = udpDestination[0] + udpDestination[1];          //UDP目的IP地址
            udphead[3] = udpDestination[2] + udpDestination[3];
            return true;
        }                                                                         //ip正则校验
        private bool IsIP(string ip)
        {                                                                //判断是否为IP,加上是否有划分校验(\/[012]?\d|3[0-2])?
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?(\/[012]?\d|\/3[0-2])?)$");
        }                                                                         //递归计算UDP头部所有十六进制数的和
        private string CacuSum(string a, int i)
        {
            string tmp = TwoSum(a, udphead[i]);
            if (i + 1 == 14)
            {
                allSum = tmp;
                return tmp;
            }
            CacuSum(tmp, i + 1);
            return "";
        }                                                                        //计算两个十六进制数的和
        private string TwoSum(string a, string b)
        {
            int aint = 0, bint = 0;
            int flag = a.Length;
            for (int i = 0; i < a.Length; i++)
            {
                flag--;
                aint += JudgeLoc(a[i]) * Convert.ToInt32(Math.Pow(16, flag));
            }
            flag = b.Length;
            for (int i = 0; i < b.Length; i++)
            {
                flag--;
                bint += JudgeLoc(b[i]) * Convert.ToInt32(Math.Pow(16, flag));
            }
            string Sum = Convert.ToString(aint + bint, 16).PadLeft(4, '0'); //存和的十六进制
            return Sum;
        }                                                                            //计算十六进制字符对应的整型值
        private int JudgeLoc(char c)
        {
            if (c > '0' && c <= '9')
            {
                return c - '0';
            }
            else if (c >= 'a' && c <= 'f')
            {
                return c - 'a' + 10;
            }
            return 0;
        }                                                                           //十六进制转二进制并进行取反操作
        private string ConvertHexToBin(string hex)
        {
            int aint = 0;
            int flag = hex.Length;
            for (int i = 0; i < hex.Length; i++)
            { 
                flag--;                                                     //调用十六进制转二进制的函数JudgeLoc
                aint += JudgeLoc(hex[i]) * Convert.ToInt32(Math.Pow(16, flag));
            }
            string bina = Convert.ToString(aint, 2).PadLeft(16, '0');       //十六进制转二进制部分的代码                                                                            //二进制按位取反                                              
            string confBina = "";                                            
            for (int i = 0; i < bina.Length; i++)
            {
                char sigBina = bina[i];
                if (sigBina == '0')
                {
                    sigBina = '1';
                }
                else
                {
                    sigBina = '0';
                }
                confBina += sigBina;
            }
            return confBina;
        }
        private string Cumulativesum(string hex)
        {
            int aint = 0;
            int flag = hex.Length;
            for (int i = 0; i < hex.Length; i++)
            {
                flag--;
                aint += JudgeLoc(hex[i]) * Convert.ToInt32(Math.Pow(16, flag));
            }
            string bina = Convert.ToString(aint, 2).PadLeft(16, '0');
            return bina;
        }
        private void Button2_Click(object sender, EventArgs e)               //校验和转换为十六进制
        {
            if (!InfoCheck())
            {
                return;
            }
            udphead[9] = "0000";
            CacuSum(udphead[0], 1);
            string overflow = "";
            if (allSum.Length > 4)                                            //溢出处理
            {
                for (int i = 0; i < allSum.Length - 4; i++)
                {
                    overflow += allSum[i];
                }
            }
            allSum = allSum.Remove(0, allSum.Length - 4);
            string checksum = ConvertHexToBin(TwoSum(overflow, allSum));
            checksum = "0x" + string.Format("{0:x}", Convert.ToInt32(checksum, 2)).PadLeft(4, '0'); 
            textBox15.Text = checksum;                                       //校验和所在的框体
        }
        private void Button3_Click(object sender, EventArgs e)               //UDP包的设计和实现发送模块
        {
            Form2 form2 = new Form2();
            form2.Show();
        }
        private void Button4_Click(object sender, EventArgs e)         
        {                                                                             //新建文件
            FileStream file = new FileStream("d:/IP_Information.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
            StreamWriter writer = new StreamWriter(file, Encoding.UTF8);     //中文乱码的解决办法
            writer.WriteLine(
                    label2.Text + "\n" 
                  + textBox2.Text + "\0\0" + textBox3.Text  + "\n"           //UDP伪首部数据保存
                  + textBox4.Text + "\0\0" + textBox5.Text  + '\n'
                  + label7.Text   + "\0\0" + label8.Text    + "\0\0" + label9.Text   + "\n"
                  + "\0\0" + textBox6.Text + "\0\0\0\0\0\0" + textBox22.Text + "\0\0\0\0\0\0" + textBox8.Text + "\r\r\r"                  
                  + label3.Text   + "\n" 
                  + label10.Text  + "\0\0" + label11.Text   + "\n"            //UDP首部数据保存
                  + textBox9.Text + "\0\0\0\0\0\0\0\0" + textBox10.Text + "\n" 
                  + label12.Text  + "\0\0" + label13.Text   + "\n"
                  + textBox11.Text+ "\0\0\0\0\0\0\0" + textBox12.Text + "\r\r\r"                                                                              //UDP数据长度保存
                  + label1.Text   + "\n"  
                  + textBox1.Text + "\0\0" + textBox7.Text  + "\0\0" + textBox16.Text + "\0\0" + textBox17.Text + "\n"
                  + textBox21.Text+ "\0\0" + textBox20.Text + "\0\0" + textBox19.Text + "\0\0" + textBox18.Text + "\r\r\r"
                                                                              //其他数据的保存
                  + label4.Text   + "\0\0" + textBox13.Text + "\n"
                  + label5.Text   + "\0\0" + textBox14.Text + "\n"
                  + label6.Text   + "\0\0" + textBox15.Text
                             );
            writer.Close();
            file.Close();                                                    //最后要关闭写入状态
            MessageBox.Show("IP_Information文件已保存至D盘根目录下!");       
        }
        private void TextBox3_TextChanged(object sender, EventArgs e)
        {
        }
        private void TextBox2_TextChanged(object sender, EventArgs e)
        {
        }
        private void TextBox5_TextChanged(object sender, EventArgs e)
        {
        }
        private void TextBox13_TextChanged(object sender, EventArgs e)
        {
        }
        private void TextBox1_TextChanged(object sender, EventArgs e)
        {
        }
        private void TextBox16_TextChanged(object sender, EventArgs e)
        {
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        private void TextBox12_TextChanged(object sender, EventArgs e)
        {
        }
        private void label11_Click(object sender, EventArgs e)
        {
        }
        private void TextBox19_TextChanged(object sender, EventArgs e)
        {
        }
    }
}

##运行效果:

UDP的界面设计与校验和的实现展示

在这里插入图片描述
UDP数据的发送端口:
在这里插入图片描述
接收端口使用的是网络小助手,感兴趣的亲们可以在网上下载,按照网络上的教程十分的容易理解。
  这只是代码的一部分,有需要的可以来主页下载,当然了存在不足的地方希望大家可以给出宝贵的意见和建议,共同进步。第一次写考虑不周之处希望大家多多谅解。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
UDP校验和计算工具是一种用于计算UDP数据报校验和的工具UDP(用户数据报协议)是一种面向无连接的传输层协议,不像TCP那样提供可靠的数据传输,因此需要使用校验和来检测数据传输过程中的错误。 UDP校验和计算工具的主要功能是对UDP数据进行校验和的计算。校验和是通过对数据中各个字节进行加和操作,并取其反码得到的。在发送数据报之前,发送方会计算数据报的校验和,并将其添加到数据的首部。当接收方接收到数据时,会对接收到的数据进行校验和的计算,并与数据中的校验和进行比较。如果两个校验和不一致,则说明数据在传输过程中发生了错误。 计算UDP校验和的过程括以下几个步骤: 1. 将UDP数据中的数据划分成若干个16位的字块。 2. 对这些字块进行求和操作,将所有的字块相加,得到一个32位的和。 3. 将32位的和的高16位与低16位相加,直到最高位为0为止。 4. 取最终的和的反码作为校验和。 UDP校验和的计算能够帮助检测数据在传输过程中的传输错误,但并不能修复错误。因此,需要使用可靠的传输协议(如TCP)来保证数据的正确传输。UDP校验和计算工具作为一种辅助工具,可以帮助开发人员在开发和调试网络应用程序时,对UDP数据进行校验和的计算,提高数据传输的可靠性和正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诺言锡仪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值