TCP/UDP编程基础

本文介绍了使用C#进行UDP通信的步骤,包括创建项目、编写客户端和服务器端代码,并通过Wireshark抓包分析数据传输。接着展示了如何创建窗体应用,实现发送和接收端的交互,并对比了单线程与多线程的执行效果。最后探讨了端口扫描的实现过程。通过实验,验证了VS在可视化编程上的便利性,并比较了单线程与多线程的效率优势。
摘要由CSDN通过智能技术生成



1、UDP通信

1.1、创建项目

    1、首先创建一个新项目
在这里插入图片描述

    2、给项目命令
在这里插入图片描述

    3、编写代码,创建进来是系统默认的helooword程序代码
在这里插入图片描述

1.2、代码编写及运行并抓包

    1、客户端(即发送端)代码编写及运行结果

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace helloword
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] data = new byte[1024];
            string input, stringData;

            //构建TCP 服务器
            Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());

            //设置服务IP(这个IP地址是服务器的IP),设置TCP端口号
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("192.168.201.236"), 8080);

            //定义网络类型,数据连接类型和网络协议UDP
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            

            string welcome = "你好! ";
            data = Encoding.UTF8.GetBytes(welcome);
            server.SendTo(data, data.Length, SocketFlags.None, ip);
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = (EndPoint)sender;

            data = new byte[1024];
            //对于不存在的IP地址,加入此行代码后,可以在指定时间内解除阻塞模式限制
            int recv = server.ReceiveFrom(data, ref Remote);
            Console.WriteLine("Message received from {0}: ", Remote.ToString());
            Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));
            int i = 0;
            while (true)
            {
                string s = "Hello Cqjtu!重交物联2019级" + i;
                Console.WriteLine(s);
                server.SendTo(Encoding.UTF8.GetBytes(s), Remote);
                if (i == 50)
                {
                    break;
                }
                i++;
            }
            Console.WriteLine("Stopping Client.");
            server.Close();
            Console.WriteLine("数据发送完毕,按任意键退出...");
            System.Console.ReadKey();;
        }

    }
}

在这里插入图片描述

    2、服务器端(即接收端)代码编写及运行结果

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace helloeord
{
    class Program
    {
        static void Main(string[] args)
        {
            int recv;
            byte[] data = new byte[1024];

            //得到本机IP,设置TCP端口号         
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, 8080);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            //绑定网络地址
            newsock.Bind(ip);

            Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());

            //等待客户机连接
            Console.WriteLine("Waiting for a client");

            //得到客户机IP
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = (EndPoint)(sender);
            recv = newsock.ReceiveFrom(data, ref Remote);
            Console.WriteLine("Message received from {0}: ", Remote.ToString());
            Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));

            //客户机连接成功后,发送信息
            string welcome = "你好 ! ";

            //字符串与字节数组相互转换
            data = Encoding.UTF8.GetBytes(welcome);

            //发送信息
            newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
            while (true)
            {
                data = new byte[1024];
                //接收信息
                recv = newsock.ReceiveFrom(data, ref Remote);
                Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));
                //newsock.SendTo(data, recv, SocketFlags.None, Remote);
            }
        }

    }
}

在这里插入图片描述

    3、抓包实验,打开wireshark,选择wlan(即无线网络)抓取发送的数据
在这里插入图片描述
    可以看到发送的内容,其中英文可以直接看到,而汉字是经过加密的,所以不能直接显示。

2、窗体应用

2.1、创建项目

    1、使用Windows创建一个新项目
在这里插入图片描述

    2、项目命令及保存
在这里插入图片描述

    3,进行窗体的创建
在这里插入图片描述

2.2、界面编辑

    1、先将需要的控件拉进来
在这里插入图片描述

    2、点击窗体,然后再点击右下角的属性,将窗体命名为发送端
在这里插入图片描述

    3、同样将发送按钮命名为发送
在这里插入图片描述

    4、选择编辑对话内容的编辑框,找到属性中的font,设置其字体属性
在这里插入图片描述
    5、将拉进去的两个对话框分别命名,写代码的时候方便识别,可以使用其默认的
在这里插入图片描述

2.3、完善代码并运行结果并抓包

    1、完善发送端代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace testForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                /*
                 * 显示当前时间
                 */
                string str = "The current time: ";
                str += DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                textBox2.AppendText(str + Environment.NewLine);
                /*
                 * 做好连接准备
                 */
                int port = 2000;
                string host = "192.168.55.204";  //我室友的IP地址
                IPAddress ip = IPAddress.Parse(host);
                IPEndPoint ipe = new IPEndPoint(ip, port);//把ip和端口转化为IPEndPoint实例
                Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket
                /*
                 * 开始连接
                 */
                str = "Connect to server...";
                textBox2.AppendText(str + Environment.NewLine);
                c.Connect(ipe);//连接到服务器
                /*
                 *发送消息 
                 */
                string sendStr = textBox1.Text;
                str = "The message content: " + sendStr;
                textBox2.AppendText(str + Environment.NewLine);
                byte[] bs = Encoding.UTF8.GetBytes(sendStr);
                str = "Send the message to the server...";
                textBox2.AppendText(str + Environment.NewLine);
                c.Send(bs, bs.Length, 0);//发送信息
                /*
                 * 接收服务器端的反馈信息
                 */
                string recvStr = "";
                byte[] recvBytes = new byte[1024];
                int bytes;
                bytes = c.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息
                recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
                str = "The server feedback: " + recvStr;//显示服务器返回信息
                textBox2.AppendText(str + Environment.NewLine);
                /*
                 * 关闭socket
                 */
                c.Close();
            }
            catch (ArgumentNullException f)
            {
                string str = "ArgumentNullException: " + f.ToString();
                textBox2.AppendText(str + Environment.NewLine);
            }
            catch (SocketException f)
            {
                string str = "ArgumentNullException: " + f.ToString();
                textBox2.AppendText(str + Environment.NewLine);
            }
            textBox2.AppendText("" + Environment.NewLine);
            textBox1.Text = "";
        }
    }
}

    2、然后完成接收端代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * 做好连接准备
             */
            int i = 0;
            int port = 2000;
            string host = "192.168.55.204";
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket类
            s.Bind(ipe);//绑定2000端口
            /*
             * 循环监听并处理消息
             */
            while (true)
            {
                i++;
                try
                {
                    Console.Write("Perform operations {0} :", i);
                    Console.WriteLine("\t-----------------------------------------------");
                    s.Listen(0);//开始监听
                    Console.WriteLine("1. Wait for connect...");
                    /*
                     * 实例一个新的socket端口
                     */
                    Socket temp = s.Accept();//为新建连接创建新的Socket。
                    Console.WriteLine("2. Connect successful");
                    /*
                     * 接收客户端发的消息并做解码处理
                     */
                    string recvStr = "";
                    byte[] recvBytes = new byte[1024];
                    int bytes;
                    bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息
                    recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
                    Console.WriteLine("3. Server Get Message:{0}", recvStr);//把客户端传来的信息显示出来
                    /*
                     * 返回给客户端连接成功的消息
                     */
                    string sendStr = "Ok!receive message sucessful!";
                    byte[] bs = Encoding.UTF8.GetBytes(sendStr);
                    temp.Send(bs, bs.Length, 0);//返回客户端成功信息
                    /*
                     * 关闭端口
                     */
                    temp.Close();
                    Console.WriteLine("4. Completed...");
                    Console.WriteLine("-----------------------------------------------------------------------");
                    Console.WriteLine("");
                    //s.Close();//关闭socket(由于再死循环中,所以不用写,但如果是单个接收,实例socket并完成任务后需关闭)
                }
                catch (ArgumentNullException e)
                {
                    Console.WriteLine("ArgumentNullException: {0}", e);
                }
                catch (SocketException e)
                {
                    Console.WriteLine("SocketException: {0}", e);
                }
            }
        }
    }
}

    3、发送端运行结果
在这里插入图片描述

    4、接收端运行结果
在这里插入图片描述

    6、同样使用无线网络(WLAN)进行抓包
在这里插入图片描述

    7、抓包结果
在这里插入图片描述
    可以看到发送的内容,其中英文可以直接看到,而汉字是经过加密的,所以不能直接显示。

3、端口扫描

    1、同样使用Windows创建一个窗体项目
在这里插入图片描述

    2、拉进来四个编辑框和一个按钮,并进行布局设计
在这里插入图片描述

    3、单线程运行结果
在这里插入图片描述

    4、多线程运行结果
在这里插入图片描述

4、总结

    通过上述的实验,发现vs来编程对于可视化的实现是非常方便的,不像其他的软件一样比较复杂,可以说是一个比较实用的软件。其次通过单线程与多线程代码实现发现多线程明显比单线程更加的好用,多线程同时支持多个线程进行,执行速度快了许多。


代码地址:https://github.com/zhao-ning9/UDP-TCP.git
参考:
https://blog.csdn.net/qq_43279579/article/details/109325176
https://blog.csdn.net/ssj925319/article/details/109336123
https://blog.csdn.net/bawei939/article/details/109826827

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值