C# 网络编程之UDP

C# 网络编程之UDP

什么是UDP

UDP是一个无连接的传输协议,它不保证可靠传输和数据的顺序,但是其传输速度很快,适合于传输实时性要求高的数据。

UDP的使用场景

由于UDP不需要建立连接,所以适合于一对多或多对多的广播传输。比如实现网络游戏的消息传输,实时视频传输等。

UDP编程实现

发送端实现

UDP发送方需要绑定发送端口,然后指定目标地址和目标端口,将要发送的数据包发送出去。

示例1:发送一个简单的字符串。

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

class Sender {
  static void Main() {
    var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
    using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
      byte[] data = Encoding.UTF8.GetBytes("Hello World!");
      socket.SendTo(data, endPoint);
    }
  }
}

示例2:发送一个自定义的数据包。

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

struct CustomPacket {
  public int id;
  public float x;
  public float y;
  public float z;
}

class Sender {
  static void Main() {
    var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
    using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
      var packet = new CustomPacket {
        id = 123,
        x = 1.0f,
        y = 2.0f,
        z = 3.0f
      };
      byte[] data = Serialize(packet);
      socket.SendTo(data, endPoint);
    }
  }

  // 自定义的序列化方法
  static byte[] Serialize<T>(T obj) {
    int size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
    byte[] data = new byte[size];
    var ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size);
    System.Runtime.InteropServices.Marshal.StructureToPtr(obj, ptr, true);
    System.Runtime.InteropServices.Marshal.Copy(ptr, data, 0, size);
    System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
    return data;
  }
}

接收端实现

UDP接收方需要绑定监听端口,然后不断从网络中读取数据包。

示例1:接收简单的字符串。

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

class Receiver {
  static void Main() {
    var endPoint = new IPEndPoint(IPAddress.Any, 12345);
    using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
      socket.Bind(endPoint);
      byte[] buffer = new byte[1024];
      int size = socket.Receive(buffer);
      string message = Encoding.UTF8.GetString(buffer, 0, size);
      Console.WriteLine(message);
    }
  }
}

示例2:接收自定义的数据包。

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

struct CustomPacket {
  public int id;
  public float x;
  public float y;
  public float z;
}

class Receiver {
  static void Main() {
    var endPoint = new IPEndPoint(IPAddress.Any, 12345);
    using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
      socket.Bind(endPoint);
      byte[] buffer = new byte[1024];
      int size = socket.Receive(buffer);
      var packet = Deserialize<CustomPacket>(buffer, size);
      Console.WriteLine(packet.id);
      Console.WriteLine(packet.x);
      Console.WriteLine(packet.y);
      Console.WriteLine(packet.z);
    }
  }

  // 自定义的反序列化方法
  static T Deserialize<T>(byte[] buffer, int size) {
    T obj = default(T);
    int objSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
    if (size == objSize) {
      var ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(objSize);
      System.Runtime.InteropServices.Marshal.Copy(buffer, 0, ptr, objSize);
      obj = (T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr, typeof(T));
      System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
    }
    return obj;
  }
}

UDP总结

UDP是一个高速传输的无连接协议,适合于实时性要求高的数据传输。使用UDP需要我们手动处理数据包的组装和拆解,同时对于丢包和乱序等问题需要自行处理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 网络编程之UDP - Python技术站

(0)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • c#生成自定义图片方法代码实例

    下面是关于使用C#生成自定义图片方法的完整攻略。 1. 确定图片尺寸和格式 生成自定义图片前,需要先确定图片的尺寸和格式。尺寸可以由用户自定义,格式可以选择常见的png、jpeg等格式。 2. 创建Bitmap对象并初始化 在C#中,使用Bitmap对象来创建和处理图片。可以使用Bitmap类的构造函数来创建一个新的Bitmap对象。例如: Bitmap b…

    C# 2023年6月7日
    00
  • WPF+SkiaSharp实现自绘拖曳小球

    WPF 是一种跨平台、络人机交互(HCI)的技术,而 SkiaSharp 是一种用于高效地进行 2D 图形渲染的跨平台、高性能的图形库。这两者的结合可以实现一些非常炫酷的效果,比如实现自绘拖曳小球。 本攻略将分为以下几个步骤: 创建 WPF 窗口; 在 WPF 窗口中引用 SkiaSharp 和 SkiaSharp.Views.Wpf,并在 XAML 中定义…

    C# 2023年6月6日
    00
  • C#多线程系列之线程等待

    下面是关于“C#多线程系列之线程等待”的完整攻略。 线程等待 在线程的执行过程中,我们可能需要等待某些线程执行完毕后再进行后续操作。下面是两种常见的线程等待方式。 Thread.Join 方法 Thread.Join 方法允许一个线程等待其他线程执行完毕后再继续执行。下面是一个示例代码: using System; using System.Threadin…

    C# 2023年5月15日
    00
  • C#实现的Socket服务器端、客户端代码分享

    接下来我将详细讲解如何实现C# Socket服务器端、客户端代码的分享。 一、概述 Socket是一种应用程序编程接口(API),用于在两个计算机之间进行网络通信。在C#中,可以使用System.Net.Sockets命名空间来创建和使用Socket。本攻略将介绍如何使用C#创建一个简单的Socket服务器端和客户端,并分享相关代码。 二、Socket服务器…

    C# 2023年6月7日
    00
  • 详解c# 可空类型(Nullable)

    详解C#可空类型(Nullable) 可空类型介绍 C#中引入了可空类型(Nullable Type)的概念,允许值类型(Value Type)中存储null值。在值类型中,如果未给该变量赋值,则该变量的值默认为0,但是如果该变量的值也可以是null,则使用可空类型来定义该变量。 可空类型可用于任何基本类型,如int,float,decimal等。 如何定义…

    C# 2023年6月7日
    00
  • csdn 博客中实现运行代码功能实现

    实现csdn博客中运行代码功能可以使用以下两种方法: 方法一:使用CSDN编辑器 登录CSDN博客后台,在编辑器的顶部菜单中点击“插入代码”按钮,或者输入“[[toc]]”快捷键,然后点击Code按钮插入代码框。 插入代码框中分别输入该段代码的语言和代码,可以选择开启行号选项和代码复制按钮选项。例如,输入以下Java代码: public class Hell…

    C# 2023年5月31日
    00
  • VS2022使用ClickOnce发布程序本地安装.net框架

    因为遇到下面的错误,没有在网上搜到详细解决问题的教程,费了一些时间才解决了问题,特此记录一下,也希望能帮助到其他人。  要在“系统必备”对话框中启用“从与我的应用程序相同的位置下载系统必备组件”,必须将“.NET 桌面运行时 6.0.14 (x64)”项的文件“net6desktopruntime_x64\windowsdesktop-runtime-6.0…

    C# 2023年5月7日
    00
  • ASP.NET Core MVC 从入门到精通之wwwroot和客户端库

    随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员。 经过前几篇文章的讲解,初步了解ASP.NET Core MVC项目创建,启…

    C# 2023年4月25日
    00
合作推广
合作推广
分享本页
返回顶部