Skip to content

add Span overloads for Socket datagram functions #938

Closed
@wfurt

Description

@wfurt

Spanification, ValueTask, and cancellation

This proposal spanifies connectionless methods on Socket, uses a ValueTask return, and adds cancellation support. There are already such overloads in Send() and Receive() functions for connection oriented sockets (TCP) and this is complement for UDP.

Proposed APIs

namespace System.Net.Sockets
{
    // Open question: consider defaulting SocketFlags to SocketFlags.None to reduce API space? Might challenge IntelliSense.

    public partial class Socket : IDisposable
    {
        // existing: public int SendTo(byte[] buffer, EndPoint remoteEP);
        public int SendTo(ReadOnlySpan<byte> buffer, EndPoint remoteEP);

        // existing: public int SendTo(byte[] buffer, SocketFlags socketFlags, EndPoint remoteEP);
        public int SendTo(ReadOnlySpan<byte> buffer, SocketFlags socketFlags, EndPoint remoteEP);

        // existing: public int ReceiveFrom(byte[] buffer, ref EndPoint remoteEP);
        public int ReceiveFrom(Span<byte> buffer, ref EndPoint remoteEP);

        // existing: public int ReceiveFrom(byte[] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP);
        public int ReceiveFrom(Span<byte> buffer, SocketFlags socketFlags, ref EndPoint remoteEP);
    }

    public static class SocketTaskExtensions
    {
        // existing: public static Task<int> SendToAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags, EndPoint remoteEP);
        public static ValueTask<int> SendToAsync(this Socket socket, ReadOnlyMemory<byte> buffer, EndPoint remoteEP, CancellationToken cancellationToken = null);
        public static ValueTask<int> SendToAsync(this Socket socket, ReadOnlyMemory<byte> buffer, SocketFlags socketFlags, EndPoint remoteEP, CancellationToken cancellationToken = null);

        // existing: public static Task<SocketReceiveFromResult> ReceiveFromAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags, EndPoint remoteEndPoint);
        public static ValueTask<SocketReceiveFromResult> ReceiveFromAsync(this Socket socket, Memory<byte> buffer, EndPoint remoteEP, CancellationToken cancellationToken = null);
        public static ValueTask<SocketReceiveFromResult> ReceiveFromAsync(this Socket socket, Memory<byte> buffer, SocketFlags socketFlags, EndPoint remoteEP, CancellationToken cancellationToken = null);

        // existing: public static Task<SocketReceiveMessageFromResult> ReceiveMessageFromAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags, EndPoint remoteEndPoint);
        public static ValueTask<SocketReceiveMessageFromResult> ReceiveMessageFromAsync(this Socket socket, Memory<byte> buffer, EndPoint remoteEP, CancellationToken cancellationToken = null);
        public static ValueTask<SocketReceiveMessageFromResult> ReceiveMessageFromAsync(this Socket socket, Memory<byte> buffer, SocketFlags socketFlags, EndPoint remoteEP, CancellationToken cancellationToken = null);
    }
}

Most of the underlying code is already ready, this is about exposing it as public API.

cc: @stephentoub

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions