欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c#如何使用UDP進(jìn)行聊天通信

 更新時(shí)間:2023年06月16日 14:43:54   作者:故里2130  
這篇文章主要介紹了c#如何使用UDP進(jìn)行聊天通信問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

c#使用UDP進(jìn)行聊天通信

UDP和TCP都是網(wǎng)絡(luò)通信中不可缺少的部分,兩者在不同的環(huán)境中,應(yīng)用的場景不一樣,UDP在網(wǎng)絡(luò)不好的情況下,傳輸會丟包,也就是會丟數(shù)據(jù),而TCP不會這樣,所以重要的數(shù)據(jù)使用TCP傳輸,但是TCP對網(wǎng)絡(luò)的資源消耗非常的大,例如視頻,音頻等大量的數(shù)據(jù),這個(gè)時(shí)候就選擇UDP,因?yàn)閁DP占用網(wǎng)絡(luò)資源比較低,就算丟一幀二幀的圖像的數(shù)據(jù),也不會有影響的。

UDP只管發(fā)送,不管你有沒有接收到信息,比較主動(dòng),同理,也會一直接收,只要在線,就能接受對方的信息。UDP比TCP的使用更加的簡單。

UDP通信可以分為使用UDP和UdpClient。UdpClient是Socket的一種封裝。其實(shí)UDP通信沒有絕對的服務(wù)端和客戶端分別,因?yàn)槎际沁B接上,就可以發(fā)送和接收。

使用UDP方式,需要注意發(fā)送消息的IP地址和端口與接收消息的IP地址和端口。

服務(wù)端代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //udp 服務(wù)端
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001));//綁定端口號和IP
            Console.WriteLine("服務(wù)端已經(jīng)開啟");
            Thread t = new Thread(()=>ReciveMsg(server));//開啟接收消息線程
            t.Start();
            Thread t2 = new Thread(()=>sendMsg(server));//開啟發(fā)送消息線程
            t2.Start();
        }
        static void sendMsg(Socket server)
        {
            EndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6000);    //向指定的IP和端口發(fā)送消息
            while (true)
            {
                string msg = Console.ReadLine();
                server.SendTo(Encoding.UTF8.GetBytes(msg), point);
            }
        }
        static void ReciveMsg(Socket server)
        {
            while (true)
            {
                //EndPoint point = new IPEndPoint(IPAddress.Any, 0);                   //向所有的IP和端口接收消息
                EndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6000);   //向指定的IP和端口接收消息
                byte[] buffer = new byte[1024];
                int length = server.ReceiveFrom(buffer, ref point);//接收數(shù)據(jù)報(bào)
                string message = Encoding.UTF8.GetString(buffer, 0, length);
                Console.WriteLine("收到了消息:" + message);
            }
        }
    }
}

客戶端代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            client.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6000));
            Thread t = new Thread(() => sendMsg(client));
            t.Start();
            Thread t2 = new Thread(() => ReciveMsg(client));
            t2.Start();
            Console.WriteLine("客戶端已經(jīng)開啟");
        }
        static void sendMsg(Socket client)
        {
            EndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001);    //向指定的IP和端口發(fā)送消息
            while (true)
            {
                string msg = Console.ReadLine();
                client.SendTo(Encoding.UTF8.GetBytes(msg), point);
            }
        }
        static void ReciveMsg(Socket client)
        {
            while (true)
            {
                //EndPoint point = new IPEndPoint(IPAddress.Any, 0);                        //向所有的IP和端口接收消息
                EndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001);        //向指定的IP和端口接收消息
                byte[] buffer = new byte[1024];
                int length = client.ReceiveFrom(buffer, ref point);//接收數(shù)據(jù)報(bào)
                string message = Encoding.UTF8.GetString(buffer, 0, length);
                Console.WriteLine("收到了消息:" + message);
            }
        }
    }
}

效果預(yù)覽

使用UdpClient方式,需要注意發(fā)送消息的IP地址和端口與接收消息的IP地址和端口

服務(wù)端代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //創(chuàng)建udpclient 綁定ip跟端口號
            UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090));
            Console.WriteLine("UdpClient服務(wù)端已經(jīng)開啟");
            Thread t = new Thread(() => ReciveMsg(udpClient));//開啟接收消息線程
            t.Start();
            Thread t2 = new Thread(() => sendMsg(udpClient));//開啟發(fā)送消息線程
            t2.Start();
        }
        static void sendMsg(UdpClient udpClient)
        {
            while (true)
            {
                string message = Console.ReadLine();
                byte[] data = Encoding.UTF8.GetBytes(message);
                udpClient.Send(data, data.Length, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8091));   //發(fā)送到指定的IP地址和端口信息
            }
        }
        static void ReciveMsg(UdpClient udpClient)
        {
            while (true)
            {
                //接收數(shù)據(jù)
                //IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);                     //接收所有的IP地址和端口信息
                IPEndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8091);     //接收指定的IP地址和端口信息
                byte[] data = udpClient.Receive(ref point);// 
                string message = Encoding.UTF8.GetString(data);
                Console.WriteLine("收到了消息:" + message);
            }
        }
    }
}

客戶端代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            //創(chuàng)建udpclient對象
            UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8091));
            Console.WriteLine("UdpClient客戶端已經(jīng)開啟");
            Thread t = new Thread(() => sendMsg(client));
            t.Start();
            Thread t2 = new Thread(() => ReciveMsg(client));
            t2.Start();
        }
        static void sendMsg(UdpClient client)
        {
            while (true)
            {
                string message = Console.ReadLine();
                byte[] data = Encoding.UTF8.GetBytes(message);
                client.Send(data, data.Length, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090));
            }
        }
        static void ReciveMsg(UdpClient udpClient)
        {
            while (true)
            {
                //接收數(shù)據(jù)
                //IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);                      //接收所有的IP地址和端口信息
                IPEndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090);      //接收指定的IP地址和端口信息
                byte[] data = udpClient.Receive(ref point); 
                string message = Encoding.UTF8.GetString(data);
                Console.WriteLine("收到了消息:" + message);
            }
        }
    }
}

效果預(yù)覽

從以上的案例來看,UDP和UdpClient的區(qū)別基本上都是一樣的,一個(gè)使用了Socket 類,一個(gè)使用了UdpClient類,然后都是綁定對應(yīng)的IP地址和端口,然后就是分別調(diào)用Socket類的方法,進(jìn)行發(fā)送消息和接收消息,調(diào)用UdpClient類的方法,進(jìn)行發(fā)送消息和接收信息。

其實(shí)在新建類的時(shí)候,可以不用先進(jìn)行連接,可以把IP地址和端口,以及消息一次性發(fā)出去。

拓展

單播,廣播,多播三者的區(qū)別

單播

用于兩個(gè)主機(jī)之間的端對端通信,指定了固定的IP地址和端口,就是一對一的對話,其他人聽不到你們說的話,類似私聊。

代碼:就是上面的代碼,指定了固定的IP地址和端口號,發(fā)送和接收都互相對應(yīng)。

廣播

用于一個(gè)主機(jī)對整個(gè)局域網(wǎng)上所有主機(jī)上的數(shù)據(jù)通信,就是一個(gè)人大聲說話,所有的人都能聽到,類似群聊。

代碼:修改成下面2句即可,發(fā)送端和接收端都要修改。

UDP服務(wù)端

 server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);    //Broadcast開啟廣播
 EndPoint point = new IPEndPoint(IPAddress.Broadcast, 4567);    //開啟廣播,端口是4567

UDP客戶端

 EndPoint iep = new IPEndPoint(IPAddress.Any, 4567);      //任意ip,端口就是服務(wù)端的4567
 EndPoint point = new IPEndPoint(IPAddress.Any, 4567);        //廣播,端口是4567

UdpClient服務(wù)端

            UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
            IPEndPoint point = new IPEndPoint(IPAddress.Broadcast, 4567);    //開啟廣播,端口是4567

UdpClient客戶端

 

            UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 4567));
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);

多播

介于單播和廣播之間,也叫組播,從名字上面就能知道,建立一個(gè)組,然后向組內(nèi)的人員發(fā)送消息,就類似,微信臨時(shí)拉一個(gè)群,指定群內(nèi)的人,向群內(nèi)通知信息。

代碼:修改成下面2句即可,發(fā)送端和接收端都要修改。

加入多播

                udpClient.JoinMulticastGroup(IPAddress.Parse("224.0.0.0"));//將 UdpClient 添加到多播組;IPAddress.Parse將IP地址字符串轉(zhuǎn)換為IPAddress 實(shí)例
                IPEndPoint multicast = new IPEndPoint(IPAddress.Parse("224.0.0.0"), 7788); //將網(wǎng)絡(luò)終結(jié)點(diǎn)表示為 IP 地址和端口號  7788是目的端口

退出多播

udpClient.DropMulticastGroup(IPAddress.Parse("224.0.0.0"));//將 UdpClient 從多播組中移除;IPAddress.Parse將IP地址字符串轉(zhuǎn)換為IPAddress 實(shí)例
                IPEndPoint multicast = new IPEndPoint(IPAddress.Parse("224.0.0.0"), 7788); //將網(wǎng)絡(luò)終結(jié)點(diǎn)表示為 IP 地址和端口號  7788是目的端口

帶界面操作

代碼 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;//在其他線程中可以調(diào)用主窗體控件
        }
        UdpClient udpClient;
        UdpClient client;
        private void Form1_Load(object sender, EventArgs e)
        {
            Thread js = new Thread(() =>
            {
                client = new UdpClient(new IPEndPoint(IPAddress.Any, 4567));
                IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Any, 0);
                while (true)
                {
                    try
                    {
                        if (client.Available <= 0) continue;
                        if (client.Client == null) return;
                        byte[] bytes = client.Receive(ref iPEndPoint);
                        string str = Encoding.Default.GetString(bytes);
                        //Invoke(new Action(() => textBox2.Text = str));
                        textBox2.Text = str;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    Thread.Sleep(1000);
                }
            });
            js.Start();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
            IPEndPoint point = new IPEndPoint(IPAddress.Broadcast, 4567);    //開啟廣播,端口是4567
            if (textBox1.Text != null)
            {
                Byte[] sendBytes = Encoding.Default.GetBytes(textBox1.Text);
                udpClient.Send(sendBytes, sendBytes.Length, point);
            }
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            udpClient.Dispose();
            udpClient.Close();
            client.Dispose();
            client.Close();
        }
    }
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論