KcpTransport:高性能实时网络通信的C实现

KcpTransport:高性能实时网络通信的C#实现

KcpTransport KcpTransport is a Pure C# implementation of RUDP for high-performance real-time network communication KcpTransport 项目地址: https://gitcode.com/gh_mirrors/kc/KcpTransport

项目介绍

KcpTransport 是一个纯C#实现的RUDP(Reliable User Datagram Protocol)库,专为高性能实时网络通信设计。它提供了类似于 System.Net.QuicKcpListenerKcpConnectionKcpStream,所有读写操作都基于流的方式进行,类似于TCP中的 NetworkStream。KcpTransport 提供了一个易于使用且现代的异步API,支持 async/await,并且未来计划实现对ASP.NET Kestrel Transport的支持,以便替换gRPC和MagicOnion的传输层。

项目技术分析

KcpTransport 基于KCP协议,KCP是一种高效的可靠UDP传输协议,广泛应用于需要实时性能的场景,如游戏、音视频传输等。KCP本身没有系统调用,因此可以完全在C#中实现,并利用.NET最新的UDP Socket改进和 async/await 支持。

KcpTransport 实现了Syn Cookie握手、连接管理、不可靠通信和KeepAlive等功能,未来还将支持加密。它目前仅支持 .NET 8,但计划未来支持 .NET Standard 2.1Unity

项目及技术应用场景

KcpTransport 适用于以下场景:

  • 实时游戏:需要低延迟和高可靠性的网络通信。
  • 音视频传输:需要快速传输和重传机制的应用。
  • 分布式系统:需要高效可靠的点对点通信。
  • IoT设备:需要轻量级且高效的通信协议。

项目特点

  1. 高性能:基于KCP协议,提供高效的可靠UDP传输。
  2. 纯C#实现:无需依赖外部库,完全在C#中实现。
  3. 现代异步API:支持 async/await,简化异步编程。
  4. 流式操作:所有读写操作基于流,类似于TCP的 NetworkStream
  5. 多平台支持:未来计划支持 .NET Standard 2.1Unity
  6. 低延迟:适用于需要实时性能的应用场景。

快速开始

KcpTransport 通过NuGet分发,当前仅支持 .NET 8。你可以通过以下命令安装:

PM> Install-Package KcpTransport

在服务器端,使用 KcpListener.ListenAsync 来生成连接;在客户端,使用 KcpConnection.ConnectAsync 来连接服务器。通过 OpenOutboundStreamAsync 获取用于读写操作的 Stream

using KcpTransport;
using System.Text;

var server = RunEchoServer();
var client = RunEchoClient();

await await Task.WhenAny(server, client);

static async Task RunEchoServer()
{
    var listener = await KcpListener.ListenAsync("127.0.0.1", 11000);

    while (true)
    {
        var connection = await listener.AcceptConnectionAsync();
        ConsumeClient(connection);
    }

    static async void ConsumeClient(KcpConnection connection)
    {
        using (connection)
        using (var stream = await connection.OpenOutboundStreamAsync())
        {
            try
            {
                var buffer = new byte[1024];
                while (true)
                {
                    var len = await stream.ReadAsync(buffer);
                    var str = Encoding.UTF8.GetString(buffer, 0, len);
                    Console.WriteLine("Server Request  Received: " + str);
                    await stream.WriteAsync(Encoding.UTF8.GetBytes(str));
                }
            }
            catch (KcpDisconnectedException)
            {
                Console.WriteLine($"Disconnected, Id:{connection.ConnectionId}");
            }
        }
    }
}

static async Task RunEchoClient()
{
    using var connection = await KcpConnection.ConnectAsync("127.0.0.1", 11000);
    using var stream = await connection.OpenOutboundStreamAsync();

    var buffer = new byte[1024];
    while (true)
    {
        Console.Write("Input Text:");
        var inputText = Console.ReadLine();
        await stream.WriteAsync(Encoding.UTF8.GetBytes(inputText!));
        var len = await stream.ReadAsync(buffer);
        var str = Encoding.UTF8.GetString(buffer, 0, len);
        Console.WriteLine($"Client Response Received: " + str);
    }
}

配置选项

KcpListenerKcpConnection 在创建时可以传递选项进行配置,例如:

var listener = await KcpListener.ListenAsync(new KcpListenerOptions
{
    ListenEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), listenPort),
    EventLoopCount = 1,
    KeepAliveDelay = TimeSpan.FromSeconds(10),
    ConnectionTimeout = TimeSpan.FromSeconds(20),
});

低级API

KcpTransport 还提供了低级API,直接使用 ikcp.cikcp.h 中定义的方法。通过 KcpTransport.LowLevel.KcpMethods,你可以直接调用 ikcp_*** 函数。

using KcpTransport;
using KcpTransport.LowLevel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using static KcpTransport.LowLevel.KcpMethods;

public class SampleLowLevel : IDisposable
{
    GCHandle user;
    unsafe IKCPCB* kcp;
    bool isDisposed;
    readonly long startingTimestamp;

    public unsafe SampleLowLevel(uint conversationId, delegate* managed<byte*, int, IKCPCB*, void*, int> output, object user)
    {
        this.user = GCHandle.Alloc(this);
        this.kcp = ikcp_create(conv: conversationId, user: (void*)GCHandle.ToIntPtr(this.user));
        ikcp_setoutput(kcp, output);
        this.startingTimestamp = Stopwatch.GetTimestamp();
        Update();
    }

    public unsafe int Send(ReadOnlySpan<byte> data)
    {
        fixed (byte* ptr = data)
        {
            return ikcp_send(kcp, ptr, data.Length);
        }
    }

    public unsafe int InputData(ReadOnlySpan<byte> data)
    {
        fixed (byte* ptr = data)
        {
            return ikcp_input(kcp, ptr, data.Length);
        }
    }

    public unsafe int PeekSize()
    {
        return ikcp_peeksize(kcp);
    }

    public unsafe int ReceiveData(Span<byte> buffer)
    {
        fixed (byte* ptr = buffer)
        {
            return ikcp_recv(kcp, ptr, buffer.Length);
        }
    }

    public unsafe void Update()
    {
        var elapsed = Stopwatch.GetElapsedTime(startingTimestamp);
        var currentTimestamp = (uint)(elapsed.TotalMilliseconds * 1000);
        ikcp_update(kcp, currentTimestamp);
    }

    public void Dispose()
    {
        if (!isDisposed)
        {
            isDisposed = true;
            unsafe
            {
                ikcp_release(kcp);
            }
            user.Free();
        }
    }
}

KcpTransport 是一个强大的工具,适用于需要高性能实时网络通信的场景。无论是游戏开发、音视频传输还是分布式系统,KcpTransport 都能为你提供稳定、高效的解决方案。赶快尝试一下吧!

KcpTransport KcpTransport is a Pure C# implementation of RUDP for high-performance real-time network communication KcpTransport 项目地址: https://gitcode.com/gh_mirrors/kc/KcpTransport

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

Disconnecting connection: Mirror.NetworkConnectionToServer because handling a message of type Mirror.SpawnMessage caused an Exception. This can happen if the other side accidentally (or an attacker intentionally) sent invalid data. Reason: System.IO.EndOfStreamException: ReadBlittable<System.Byte> not enough data in buffer to read 1 bytes: [FF-FF-FF-FF-FF-FF-FF-FF-03-01-02-00-00-00-35-01-14-00-00-00-8C-2E-E7-3C-66-38-FB-3D-CF-ED-17-3B-A9-76-15-35-ED-54-53-31-8D-6F-A3-B6-00-00-80-3F-6D-23-88-23-3D-6A-1F-3D-47-E3-94-A2-00-00-00-00-00-00-00-00-9B-84-D0-36-00-00-80-3F-F2-31-E5-AA-8F-E2-0B-3D-94-B3-7D-A6-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-AF-2A-C9-B1-14-26-FC-3C-A4-94-3B-25-1C-80-8B-35-E1-1F-83-BB-C7-16-BF-B7-7A-FF-7F-3F-07-F8-44-34-47-D2-02-3E-CB-4F-31-B2-A9-76-15-35-E9-05-37-31-41-57-5F-B4-00-00-80-3F-14-6D-23-24-33-07-14-3D-9E-CD-52-A4-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-C8-0D-99-B4-3D-B6-0D-3D-82-0A-4F-A6-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-FE-9A-A3-34-99-BD-16-3D-80-F5-20-A6-29-E0-B2-B5-FF-0E-96-BB-DF-7A-2B-3A-4D-FF-7F-3F-EF-91-41-BD-5B-66-DF-3D-AF-32-14-3B-EA-66-3F-36-EA-20-52-31-31-E7-13-B9-00-00-80-3F-E9-F5-97-24-FE-6F-29-3D-6E-5D-DB-23-A8-CC-C7-B6-BF-88-16-B1-8C-E0-C0-39-FF-FF-7F-3F-4C-02-9E-A7-A0-91-D4-3C-AE-C0-27-25-0D-90-75-36-DF-25-67-B0-F8-F8-70-B9-00-00-80-3F-DC-FF-55-27-EB-85-EF-3C-99-D8-DD-A3-46-E6-8C-B5-69-58-86-BB-EC-BF-16-3A-70-FF-7F-3F-1C-96-B5-BC-50-C5-F8-3D-D4-A2-D1-B8-A8-76-15-35-BE-C3-52-31-28-4D-A0-B6-00-00-80-3F-A5-39-D7-A2-33-81-13-3D-DB-B9-1A-25-FA-CE-1A-B6-65-C5-A3-AD-17-69-07-37-00-00-80-3F-FB-D4-00-28-AE-77-07-3D-1D-78-11-27-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-9D-C6-81-34-1F-EB-15-3D-4B-51-35-34-3F-5F-0E-37-20-5E-F2-BB-2A-0D-4A-BA-30-FE-7F-3F-F3-00-F6-3C-8B-30-1B-3D-69-88-B1-3C-9B-F4-8E-BE-9A-27-E1-BE-B7-CD-A6-3C-8C-76-5A-BF-12-E8-45-24-9E-5A-42-3D-59-49-EF-25-4B-12-E9-36-72-51-C4-AC-8D-A1-57-B5-00-00-80-3F-7E-00-D4-27-F3-7D-33-3D-F5-DE-67-29-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-13-44-5C-33-0F-AF-0D-3D-05-A1-8A-31-87-DC-15-3C-19-A7-00-BE-BC-9A-93-BD-24-4A-7D-3F-10-8C-2E-E7-3C-66-38-FB-3D-CF-ED-17-3B-FF-FD-F7-DF-10-6D-23-88-23-3D-6A-1F-3D-47-E3-94-A2-FF-FD-F7-DF-10-F2-31-E5-AA-8F-E2-0B-3D-94-B3-7D-A6-FF-FD-F7-DF-10-AF-2A-C9-B1-14-26-FC-3C-A4-94-3B-25-FF-F1-F7-DF-10-07-F8-44-34-47-D2-02-3E-CB-4F-31-B2-FF-FD-F7-DF-10-14-6D-23-24-33-07-14-3D-9E-CD-52-A4-FF-FD-F7-DF-10-C8-0D-99-B4-3D-B6-0D-3D-82-0A-4F-A6-FF-FD-F7-DF-10-FE-9A-A3-34-99-BD-16-3D-80-F5-20-A6-FF-F1-F7-DF-10-EF-91-41-BD-5B-66-DF-3D-AF-32-14-3B-FF-FD-F7-DF-10-E9-F5-97-24-FE-6F-29-3D-6E-5D-DB-23-FF-FD-F7-DF-10-4C-02-9E-A7-A0-91-D4-3C-AE-C0-27-25-FF-FD-F7-DF-10-DC-FF-55-27-EB-85-EF-3C-99-D8-DD-A3-FF-F1-F7-DF-10-1C-96-B5-BC-50-C5-F8-3D-D4-A2-D1-B8-FF-FD-F7-DF-10-A5-39-D7-A2-33-81-13-3D-DB-B9-1A-25-FF-FD-F7-DF-10-FB-D4-00-28-AE-77-07-3D-1D-78-11-27-FF-FD-F7-DF-10-9D-C6-81-34-1F-EB-15-3D-4B-51-35-34-FE-E9-F7-DF-10-F3-00-F6-3C-8B-30-1B-3D-69-88-B1-3C-F0-F5-9C-EC-10-12-E8-45-24-9E-5A-42-3D-59-49-EF-25-FF-FD-F7-DF-10-7E-00-D4-27-F3-7D-33-3D-F5-DE-67-29-FF-FD-F7-DF-10-13-44-5C-33-0F-AF-0D-3D-05-A1-8A-31-CB-91-66-E0-00-00-38-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-80-3F-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-80-3F-10-85-2E-E7-BC-66-38-FB-3D-D1-ED-17-3B-FF-FD-F7-DF-10-B8-C2-43-A2-3D-6A-1F-3D-85-0B-2D-A4-FF-FD-F7-DF-10-06-B9-68-29-8F-E2-0B-3D-4D-93-8D-26-FF-FD-F7-DF-10-F8-69-5B-32-14-26-FC-3C-52-B8-11-23-FE-11-F8-DF-10-1E-96-32-B4-47-D2-02-3E-C5-4F-31-B2-FF-FD-F7-DF-10-52-54-11-A2-33-07-14-3D-F5-98-43-A5-FF-FD-F7-DF-10-93-F4-9D-34-3D-B6-0D-3D-EB-75-C3-26-FF-FD-F7-DF-10-89-45-99-B4-99-BD-16-3D-47-95-D5-A5-00-12-F8-DF-10-F3-91-41-3D-5B-66-DF-3D-AB-32-14-3B-FF-FD-F7-DF-10-F5-F0-B8-22-EB-6F-29-3D-70-0D-E9-A5-FF-FD-F7-DF-10-DE-DE-31-29-C2-91-D4-3C-52-6C-F7-A5-FF-FD-F7-DF-10-BB-72-44-A9-EB-85-EF-3C-66-56-8D-26-FD-15-F8-DF-10-26-96-B5-3C-47-C5-F8-3D-10-A3-D1-B8-FF-FD-F7-DF-10-14-75-45-23-47-81-13-3D-CD-4A-B3-A5-FF-FD-F7-DF-10-F2-4E-88-29-AE-77-07-3D-47-4E-80-A6-FF-FD-F7-DF-10-9A-C6-81-B4-1F-EB-15-3D-47-C3-F5-A5-FF-15-F8-DF-10-F0-00-F6-BC-8A-30-1B-3D-69-88-B1-3C-A0-52-57-EB-10-47-89-80-24-9E-5A-42-3D-3D-8A-0A-A5-FF-FD-F7-DF-10-D8-C8-06-27-05-7E-33-3D-9C-75-38-A9-FF-FD-F7-DF-10-23-09-F0-B3-FD-AE-0D-3D-BC-8E-79-B4-33-6E-69-E0-38-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-80-3F-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-80-3F-38-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-80-3F-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-80-3F-DD-01-1A-00-00-00-BE-53-9C-BC-D8-0C-53-BB-C1-3E-B0-3C-6D-33-BC-BA-10-82-BD-BD-D8-1C-7D-BC-E7-DE-7E-3F-4E-3D-34-B3-A5-F5-AD-3B-62-10-7B-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-AF-01-3A-B3-DD-83-85-B1-87-DA-1D-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-FC-6A-12-34-BD-5C-7C-32-87-C9-AC-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-6F-4C-25-33-CA-D9-B8-34-12-ED-AD-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-77-58-B2-3C-76-5D-2E-BB-96-00-A1-3C-A0-7A-BD-B5-9B-A7-A5-3D-D9-ED-91-37-43-29-7F-3F-20-EB-A0-B3-17-82-8D-39-44-EF-64-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-7B-5A-11-34-09-D3-0B-B1-26-35-DD-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-75-4E-40-B3-3D-E5-9C-32-E0-54-8A-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-36-C8-25-32-56-DA-A6-B3-A2-AE-9F-3C-D9-92-09-36-00-00-00-00-00-00-00-80-00-00-80-3F-F4-E1-76-BB-77-2F-3C-B8-A0-4E-B9-3C-52-03-21-BD-00-3F-11-BD-D8-40-A9-BA-0B-A4-7F-3F-2B-0A-F3-2F-7C-DA-C7-B1-57-16-77-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-4E-30-AA-B0-AF-AF-2E-34-07-58-3B-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-01-C9-40-32-A8-D7-86-B4-92-E0-CA-3C-A0-B3-33-22-00-00-80-A1-FF-FF-4F-A1-00-00-80-3F-2E-54-24-33-BE-EE-E5-B4-AF-20-CE-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-00-00-00-80-00-00-00-00-5C-8F-42-3D-32-31-8D-A4-74-BE-9B-09-32-31-8D-A4-00-00-80-3F-76-F2-14-3C-64-38-26-39-B0-38-B7-3C-02-77-F6-BC-D3-C0-CE-3C-D3-C8-5B-3A-6D-CD-7F-3F-09-C6-74-B3-07-0A-0C-AF-64-97-65-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-B6-4D-30-34-C2-77-A7-B3-89-B0-30-3D-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-62-29-20-B4-EE-C8-4B-34-50-3A-A9-3C-00-00-80-A2-00-00-00-24-00-00-40-A1-00-00-80-3F-89-37-F2-B2-6F-8A-BF-34-25-92-AE-3C-A9-17-6E-35-00-00-00-00-00-00-00-80-00-00-80-3F-18-81-E7-BC-9D-21-66-BC-6B-C6-B3-3C-60-33-FD-BD-BA-D7-BC-BE-57-78-D8-3E-70-88-51-3F-D4-A5-03-33-F7-29-2C-34-A5-61-E9-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-75-44-8C-33-84-93-8C-B2-17-FF-E6-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-ED-3C-45-B4-AA-D8-3F-33-37-B1-EB-3C-00-00-00-00-00-00-00-80-00-00-00-80-00-00-80-3F-00-00-00-00-00-00-00-00-00-00-00-00-F4-04-35-3F-00-00-00-00-00-00-00-00-F4-04-35-3F-10-00-00-00-00-A0-45-36-3E-36-5E-9A-BF-FF-FD-F7-DF-10-80-33-BA-3A-CA-A0-7C-BF-91-36-4C-3F-ED-0D-BD-A7-00-00-10-30-EB-3F-3E-CA-A0-7C-BF-91-36-4C-3F-ED-0D-BD-A7-00-00 @ 2229/2222] at Mirror.NetworkReader.ReadBlittable[T] () [0x00047] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkReader.cs:142 at Mirror.NetworkReader.ReadByte () [0x00000] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkReader.cs:182 at Mirror.NetworkBehaviour.Deserialize (Mirror.NetworkReader reader, System.Boolean initialState) [0x00003] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkBehaviour.cs:1319 at Mirror.NetworkIdentity.DeserializeClient (Mirror.NetworkReader reader, System.Boolean initialState) [0x0002c] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkIdentity.cs:1422 at Mirror.NetworkClient.ApplySpawnPayload (Mirror.NetworkIdentity identity, Mirror.SpawnMessage message) [0x000fb] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkClient.cs:1166 at Mirror.NetworkClient.OnSpawn (Mirror.SpawnMessage message) [0x0001b] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkClient.cs:1550 at (wrapper delegate-invoke) System.Action`1[Mirror.SpawnMessage].invoke_void_T(Mirror.SpawnMessage) at Mirror.NetworkClient+<>c__DisplayClass68_0`1[T].<RegisterHandler>g__HandlerWrapped|0 (Mirror.NetworkConnection _, T value) [0x00000] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkClient.cs:559 at Mirror.NetworkMessages+<>c__DisplayClass9_0`2[T,C].<WrapHandler>g__Wrapped|0 (C conn, T msg, System.Int32 _) [0x00000] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkMessages.cs:206 at Mirror.NetworkMessages+<>c__DisplayClass8_0`2[T,C].<WrapHandler>b__0 (Mirror.NetworkConnection conn, Mirror.NetworkReader reader, System.Int32 channelId) [0x000cf] in D:\unity\project\1\MR\MR\Assets\Mirror\Core\NetworkMessages.cs:179 UnityEngine.Debug:LogError (object) Mirror.NetworkMessages/<>c__DisplayClass8_0`2<Mirror.SpawnMessage, Mirror.NetworkConnection>:<WrapHandler>b__0 (Mirror.NetworkConnection,Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkMessages.cs:186) Mirror.NetworkClient:UnpackAndInvoke (Mirror.NetworkReader,int) (at Assets/Mirror/Core/NetworkClient.cs:293) Mirror.NetworkClient:OnTransportData (System.ArraySegment`1<byte>,int) (at Assets/Mirror/Core/NetworkClient.cs:369) kcp2k.KcpTransport:<Awake>b__29_2 (System.ArraySegment`1<byte>,kcp2k.KcpChannel) (at Assets/Mirror/Transports/KCP/KcpTransport.cs:117) kcp2k.KcpClient:OnData (System.ArraySegment`1<byte>,kcp2k.KcpChannel) (at Assets/Mirror/Transports/KCP/kcp2k/highlevel/KcpClient.cs:74) kcp2k.KcpPeer:TickIncoming_Authenticated (uint) (at Assets/Mirror/Transports/KCP/kcp2k/highlevel/KcpPeer.cs:402) kcp2k.KcpPeer:TickIncoming () (at Assets/Mirror/Transports/KCP/kcp2k/highlevel/KcpPeer.cs:438) kcp2k.KcpClient:TickIncoming () (at Assets/Mirror/Transports/KCP/kcp2k/highlevel/KcpClient.cs:272) kcp2k.KcpTransport:ClientEarlyUpdate () (at Assets/Mirror/Transports/KCP/KcpTransport.cs:184) Mirror.NetworkClient:NetworkEarlyUpdate () (at Assets/Mirror/Core/NetworkClient.cs:1649) Mirror.NetworkLoop:NetworkEarlyUpdate () (at Assets/Mirror/Core/NetworkLoop.cs:193)
最新发布
05-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

司莹嫣Maude

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值