[API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

Description

@wfurt

Background and motivation

This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

API Proposal

namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

API Usage

example of simple server that would process request - inspired by DNS server linked in #30797

SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

Alternative Designs

No response

Risks

This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

    Description

    @wfurt

    Background and motivation

    This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

    API Proposal

    namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

    Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

    API Usage

    example of simple server that would process request - inspired by DNS server linked in #30797

    SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

    The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

    Alternative Designs

    No response

    Risks

    This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

    Metadata

    Metadata

    Assignees

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

      Description

      @wfurt

      Background and motivation

      This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

      API Proposal

      namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

      Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

      API Usage

      example of simple server that would process request - inspired by DNS server linked in #30797

      SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

      The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

      Alternative Designs

      No response

      Risks

      This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

      Metadata

      Metadata

      Assignees

      Labels

      api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

      Type

      No type

      Projects

      No projects

        Milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

        Description

        @wfurt

        Background and motivation

        This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

        API Proposal

        namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

        Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

        API Usage

        example of simple server that would process request - inspired by DNS server linked in #30797

        SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

        The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

        Alternative Designs

        No response

        Risks

        This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

        Metadata

        Metadata

        Assignees

        Labels

        api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

        Type

        No type

        Projects

        No projects

          Milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

          Description

          @wfurt

          Background and motivation

          This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

          API Proposal

          namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

          Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

          API Usage

          example of simple server that would process request - inspired by DNS server linked in #30797

          SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

          The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

          Alternative Designs

          No response

          Risks

          This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

          Metadata

          Metadata

          Assignees

          Labels

          api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

          Type

          No type

          Projects

          No projects

            Milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

            Description

            @wfurt

            Background and motivation

            This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

            API Proposal

            namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

            Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

            API Usage

            example of simple server that would process request - inspired by DNS server linked in #30797

            SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

            The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

            Alternative Designs

            No response

            Risks

            This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

            Metadata

            Metadata

            Assignees

            Labels

            api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

            Type

            No type

            Projects

            No projects

              Milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

              Description

              @wfurt

              Background and motivation

              This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

              API Proposal

              namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

              Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

              API Usage

              example of simple server that would process request - inspired by DNS server linked in #30797

              SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

              The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

              Alternative Designs

              No response

              Risks

              This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

              Metadata

              Metadata

              Assignees

              Labels

              api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

              Type

              No type

              Projects

              No projects

                Milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                [API Proposal]: add overloads with SocketAddress to Socket's SendTo and ReceiveFrom #87397

                Description

                @wfurt

                Background and motivation

                This is subset from #30797. There is long discussion about how to make sending and receiving UDP more efficient. Current overloads allocate a lot for each packet and that kills performance and it puts lot of pressure on GC. Garbage collection has significant impact on scenarios that are sensitive to timing - like multiplayer Unity games.

                API Proposal

                namespaceSystem.Net.Sockets;publicclassSocket{+publicintReceiveFrom(Span<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+publicValueTask<int>ReceiveFromAsync(Memory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);+.publicintSendTo(ReadOnlySpan<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress);+.publicValueTask<int>SendToAsync(ReadOnlyMemory<byte>buffer,SocketFlagssocketFlags,SocketAddresssocketAddress,CancellationTokencancellationToken=default);}

                Instead of allocating and returning EndPoint, we can reuse SocketAddress and we would update it in place. Ideally using API proposed in #86872 but in worst case the SocketAddress is already writable and we can play some internal tricks.

                API Usage

                example of simple server that would process request - inspired by DNS server linked in #30797

                SocketAddresssa=newSocketAddress(AddressFamily.InterNetworkV6);while(doWork){intreceivedLength=s.ReceiveFrom(buffer,SocketFlags.None,sa);response=processRequest(buffer.Slice(0,receivedLength);s.SendTo(response,SocketFlags.None,sa);}

                The async version would be basically same with addition of CancellationToken. Unlike ReceiveFromAsync that used EndPoint and returns SocketReceiveFromResult we would return ValueTask<int> just like the synchronous version and we would update socketAddress in-place.

                Alternative Designs

                No response

                Risks

                This is low-level API intended for experienced users. While there is nothing particularly dangerous one should be very careful about life cycle of the socketAddress as it can be overwritten on subsequent use.

                Metadata

                Metadata

                Assignees

                Labels

                api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SocketsblockingMarks issues that we want to fast track in order to unblock other important work

                Type

                No type

                Projects

                No projects

                  Milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions