---
id: udpsession
title: 创建UdpSession
---

import Tag from "@site/src/components/Tag.js";

### 定义

命名空间：TouchSocket.Sockets <br/>
程序集：[TouchSocket.dll](https://www.nuget.org/packages/TouchSocket)

## 一、说明

UDP组件是基于UDP协议的最基础组件，其功能简单，易用。它既能充当服务器，又能够作为客户端。

## 二、产品特点

- 简单易用。
- 多线程重叠IO。
- 内存池
- 高性能
- 支持组播、广播
- 支持插件扩展
- 支持跨平台

## 三、产品应用场景

- UDP基础使用场景：可跨平台、跨语言使用。

## 四、支持插件接口

|  插件方法| 功能 |
| --- | --- |
| IUdpReceivedPlugin | 在收到数据时触发 |

## 五、使用UdpSession

### 5.1 作为服务器使用

```csharp showLineNumbers
var udpService = new UdpSession();
udpService.Received = (c,e) =>
{
    Console.WriteLine(e.ByteBlock.ToString());
    return EasyTask.CompletedTask;
};
udpService.Setup(new TouchSocketConfig()
    .SetBindIPHost(new IPHost(7789)));
udpService.Start();
Console.WriteLine("等待接收");
```

### 5.2 作为客户端使用

```csharp showLineNumbers
var udpClient = new UdpSession();
udpClient.Setup(new TouchSocketConfig()
    //.UseUdpReceive()//作为客户端时，如果需要接收数据，那么需要绑定端口。要么使用SetBindIPHost指定端口，要么调用UseUdpReceive绑定随机端口。
    .SetBindIPHost(new IPHost(7788)));
udpClient.Start();
```

:::caution 注意

1. 即使不监听地址，Setup和Start都是必须要的。
2. 当udp作为客户端时，Config如果不设置SetBindIPHost，将不会接收，如果不知道绑定那个端口，可以直接绑定0端口(或者使用UseUdpReceive)，这样，就会使用系统空闲的一个端口了。

:::  

## 六、发送数据

框架内置很多发送发送。但是大致可分为两种。一种是带参数`EndPoint`，和一种不带的。

### 6.1 发送到指定地址

带`EndPoint`，即表示可以发送到任意终结点。

```csharp showLineNumbers
public virtual void Send(EndPoint remoteEP, byte[] buffer, int offset, int length)
```

### 6.2 发送到接收数据的地址

一般的，当udp收到数据时，都能获取到`UdpReceivedDataEventArgs`参数。然后通过该参数，能获取到接收数据的`EndPoint`。然后向这个终结点发送数据。发送方就能收到数据。

例如：

```csharp {5} showLineNumbers
class MyPluginClass : PluginBase, IUdpReceivedPlugin
{
    public async Task OnUdpReceived(IUdpSession client, UdpReceivedDataEventArgs e)
    {
        await client.SendAsync(e.EndPoint, "RRQM");
        await e.InvokeNext();
    }
}
```

### 6.3 发送到默认地址

不带`EndPoint`，即表示直接发送到默认（通过`SetRemoteIPHost`设置）的终结点。这一般在Udp作为客户端时是有用的。

```csharp showLineNumbers
public virtual void Send(byte[] buffer, int offset, int length)
```



## 七、接收数据

### 7.1 委托接收

委托接收，则是直接订阅Received即可。

```csharp showLineNumbers
var udpService = new UdpSession();
udpService.Received = (c, e) =>
{
    Console.WriteLine(e.ByteBlock.ToString());
    return EasyTask.CompletedTask;
};
udpService.Start(7789);
```

### 7.2 插件接收 <Tag>推荐</Tag>

使用插件接收，可以很好的分离业务。

声明插件

```csharp showLineNumbers
class MyPluginClass1 : PluginBase, IUdpReceivedPlugin
{
    public async Task OnUdpReceived(IUdpSession client, UdpReceivedDataEventArgs e)
    {
        var msg = e.ByteBlock.ToString();
        if (msg == "hello")
        {
            Console.WriteLine("已处理Hello");
        }
        else
        {
            //如果判断逻辑发现此处无法处理，即可转到下一个插件
            await e.InvokeNext();
        }
    }
}

class MyPluginClass2 : PluginBase, IUdpReceivedPlugin
{
    public async Task OnUdpReceived(IUdpSession client, UdpReceivedDataEventArgs e)
    {
        var msg = e.ByteBlock.ToString();
        if (msg == "hi")
        {
            Console.WriteLine("已处理Hi");
        }
        else
        {
            //如果判断逻辑发现此处无法处理，即可转到下一个插件
            await e.InvokeNext();
        }
    }
}
```

使用插件

```csharp showLineNumbers {6-7}
var udpService = new UdpSession();
udpService.Setup(new TouchSocketConfig()
    .SetBindIPHost(new IPHost(7789))
    .ConfigurePlugins(a =>
    {
        a.Add<MyPluginClass1>();
        a.Add<MyPluginClass2>();
    }));
udpService.Start();
```

[本文示例Demo](https://gitee.com/RRQM_Home/TouchSocket/tree/master/examples/Udp)