C#之UDP通讯

概述:

UDP(User Datagram Protocol)是一种无连接的、轻量级的传输协议。与TCP不同,UDP无需建立连接,就可以收发数据,因此UDP不保证数据的可靠传输,会出现丢包和乱序风险,但是其传输效率比较高,因此根据项目需要进行合理选择。UDP通讯的核心是UdpClient类,它封装了UDP协议的底层操作,提供了简单易用的接口。

使用

  • 发送端例子
    public class MainViewModel : Stylet.Screen
    {
        private UdpClient _udpClient;
        public MainViewModel()
        {
            // 注册5888端口,监听本地ip上的5888端口消息。
            // 如果不指定端口,系统会随机分配端口,每次运行程序都是不一样的端口,会很麻烦。
           // 发送方指定地址,一是为了让远端可以获取到固定的地址,二是为了接收远端发送的消息
            string localIp = "127.0.0.1";
            int localPort = 5888;
            IPAddress localAddress = IPAddress.Parse(localIp);
            IPEndPoint localPoint = new IPEndPoint(localAddress, localPort);
            _udpClient = new UdpClient(localPoint);

        }
        public void BtnSendClick(string str)
        {
            // 向指定的远端发送消息
            string remoteIPStr = "127.0.0.1";
            int remotePort = 5999;
            IPAddress ipAddress = IPAddress.Parse(remoteIPStr);
            IPEndPoint remotePoint = new IPEndPoint(ipAddress, remotePort);
            byte[] buffer = Encoding.UTF8.GetBytes("hello");
            _udpClient.Send(buffer, buffer.Length, remotePoint);
            Debug.WriteLine("已发送消息");

        }
    }
  • 接收端例子
 public partial class MainWindow : Window
 {
     private UdpClient _udpClient;
     public MainWindow()
     {
         InitializeComponent();

         // 注册5999端口,监听本地ip上的5999端口消息
         string localIp = "127.0.0.1";
         int localPort = 5999;
         IPAddress localAddress = IPAddress.Parse(localIp);
         IPEndPoint localPoint = new IPEndPoint(localAddress, localPort);
         _udpClient = new UdpClient(localPoint);

         // 准备接收远端的point对象,先随便填入值,因为Receive需要传入一个ref修饰的IPEndPoint来接受远端point
         IPEndPoint remotePoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 1);
         Task.Run(() =>
         {
             while (true)
             {
                 if (_udpClient != null)
                 {
                     var received = _udpClient.Receive(ref remotePoint);
                     string info = Encoding.UTF8.GetString(received);
                     string from = $"{remotePoint.Address}:{remotePoint.Port}";
                     Debug.WriteLine(info);//hello
                     Debug.WriteLine(from);// 127.0.0.1:5888
                 }
             }
         });
     }
 }

注意点:

  • 端口和ip地址:
    由于之前先接触的是TCP,所以刚开始对这个产生了一时疑惑。在tcp中,是存在服务端(TcpListener)和客户端(TcpClient )概念的,服务端通过tcpListener = new TcpListener(IPAddress.Parse(ipAddress), port)开启设置要监听的网口地址和端口,而客户端通过tcpClient.Connect(ipAddress, port)开启对远程地址和端口的连接,一旦建立连接后,服务端会通过TcpClient client = tcpListener.AcceptTcpClient()监听到这个客户端对象,因此双方就都可以通过client的网络流NetworkStream对象进行收发数据,也都无需知道客户端的ip地址和端口。但是UDP是无连接的,因此不管接收方还是发送方都需要_udpClient = new UdpClient(localPoint)来指定自己要监听的地址和端口,而接收方则可以通过var received = _udpClient.Receive(ref remotePoint)拿到发送方的地址和端口。

    image.png

  • Receive:
    Receive方法是阻塞方法,所以需要在新的线程内运行,程序会一直等待接收数据,当接收到一包数据时程序就返回,要持续接收数据需要重复调用Receive方法。

  • 丢包和乱序问题:
    简单的处理办法就是把包的头部固定长度的空间拿出来存放核对信息,比如包编号,如果有缺失,可以要求发送方重发,也可以进行排序。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 网络基本理论 基于TCP的网络编程 基于UDP的网络编程 ISO/OSI模型简介 ISO:国际标准化组织 OSI:...
    沉麟阅读 1,498评论 0 0
  • 支持Http、Tcp和Udp的类组成了TCP/IP三层模型(请求响应层、应用协议层、传输层)的中间层-应用协议层,...
    moshanghuakai88阅读 1,376评论 0 0
  • #一、TCP协议: TCP协议是面向有连接的,所以服务器要与客户端建立连接 服务器端: ``` using Sys...
    Nmao阅读 2,526评论 0 1
  • 需求电脑端桌面需要投屏到其他设备可能是电脑或者手机端,相反电脑端也要接收其他设备投屏过来的,这样就要做客户端和服务...
    min_dou阅读 2,288评论 1 1
  • 推送服务一般有三种实现方式: 1.轮询方式 客户端不断的查询服务器,检索新内容。这种方式的缺点十分明显,如果轮询频...
    勇敢的_心_阅读 14,097评论 3 32

友情链接更多精彩内容