diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs new file mode 100644 index 0000000000000..8f3cdbf9db07a --- /dev/null +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Receive")] + internal static extern unsafe Error Receive(SafeHandle socket, byte* buffer, int bufferLen, SocketFlags flags, int* received); + } +} diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs new file mode 100644 index 0000000000000..b4a7e1c9bc832 --- /dev/null +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Send")] + internal static extern unsafe Error Send(SafeHandle socket, byte* buffer, int bufferLen, SocketFlags flags, int* sent); + } +} diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.c b/src/libraries/Native/Unix/System.Native/pal_networking.c index ba58024472b8e..9aabac040abe7 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.c +++ b/src/libraries/Native/Unix/System.Native/pal_networking.c @@ -1348,6 +1348,34 @@ static int32_t ConvertSocketFlagsPlatformToPal(int platformFlags) ((platformFlags & MSG_CTRUNC) == 0 ? 0 : SocketFlags_MSG_CTRUNC); } +int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received) +{ + if (buffer == NULL || bufferLen < 0 || received == NULL) + { + return Error_EFAULT; + } + + int fd = ToFileDescriptor(socket); + + int socketFlags; + if (!ConvertSocketFlagsPalToPlatform(flags, &socketFlags)) + { + return Error_ENOTSUP; + } + + ssize_t res; + while ((res = recv(fd, buffer, (size_t)bufferLen, socketFlags)) < 0 && errno == EINTR); + + if (res != -1) + { + *received = (int32_t)res; + return Error_SUCCESS; + } + + *received = 0; + return SystemNative_ConvertErrorPlatformToPal(errno); +} + int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* received) { if (messageHeader == NULL || received == NULL || messageHeader->SocketAddressLen < 0 || @@ -1391,6 +1419,38 @@ int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeade return SystemNative_ConvertErrorPlatformToPal(errno); } +int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent) +{ + if (buffer == NULL || bufferLen < 0 || sent == NULL) + { + return Error_EFAULT; + } + + int fd = ToFileDescriptor(socket); + + int socketFlags; + if (!ConvertSocketFlagsPalToPlatform(flags, &socketFlags)) + { + return Error_ENOTSUP; + } + + ssize_t res; +#if defined(__APPLE__) && __APPLE__ + // possible OSX kernel bug: https://github.com/dotnet/runtime/issues/27221 + while ((res = send(fd, buffer, (size_t)bufferLen, socketFlags)) < 0 && (errno == EINTR || errno == EPROTOTYPE)); +#else + while ((res = send(fd, buffer, (size_t)bufferLen, socketFlags)) < 0 && errno == EINTR); +#endif + if (res != -1) + { + *sent = (int32_t)res; + return Error_SUCCESS; + } + + *sent = 0; + return SystemNative_ConvertErrorPlatformToPal(errno); +} + int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent) { if (messageHeader == NULL || sent == NULL || messageHeader->SocketAddressLen < 0 || @@ -1412,7 +1472,7 @@ int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, ssize_t res; #if defined(__APPLE__) && __APPLE__ - // possible OSX kernel bug: #31927 + // possible OSX kernel bug: https://github.com/dotnet/runtime/issues/27221 while ((res = sendmsg(fd, &header, socketFlags)) < 0 && (errno == EINTR || errno == EPROTOTYPE)); #else while ((res = sendmsg(fd, &header, socketFlags)) < 0 && errno == EINTR); diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.h b/src/libraries/Native/Unix/System.Native/pal_networking.h index 4cd3ca922ea52..04f26eb6650d1 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.h +++ b/src/libraries/Native/Unix/System.Native/pal_networking.h @@ -360,8 +360,12 @@ PALEXPORT int32_t SystemNative_SetReceiveTimeout(intptr_t socket, int32_t millis PALEXPORT int32_t SystemNative_SetSendTimeout(intptr_t socket, int32_t millisecondsTimeout); +PALEXPORT int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received); + PALEXPORT int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* received); +PALEXPORT int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent); + PALEXPORT int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent); PALEXPORT int32_t SystemNative_Accept(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen, intptr_t* acceptedSocket); diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index 3661f2bfafeda..8cda15170f21e 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -274,8 +274,12 @@ Link="Common\Interop\Unix\Interop.Poll.Structs.cs" /> + + > buffers, SocketFlags socketFlags, o if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"SRC:{LocalEndPoint} DST:{RemoteEndPoint}"); int bytesTransferred; - errorCode = SocketPal.Receive(_handle, buffers, ref socketFlags, out bytesTransferred); + errorCode = SocketPal.Receive(_handle, buffers, socketFlags, out bytesTransferred); #if TRACE_VERBOSE if (NetEventSource.IsEnabled) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index a0479bfc33629..9934e5c97f656 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -463,6 +463,7 @@ private abstract class ReceiveOperation : ReadOperation private sealed class BufferMemoryReceiveOperation : ReceiveOperation { public Memory Buffer; + public bool SetReceivedFlags; public BufferMemoryReceiveOperation(SocketAsyncContext context) : base(context) { } @@ -479,7 +480,17 @@ protected override bool DoTryComplete(SocketAsyncContext context) } else { - return SocketPal.TryCompleteReceiveFrom(context._socket, Buffer.Span, null, Flags, SocketAddress, ref SocketAddressLen, out BytesTransferred, out ReceivedFlags, out ErrorCode); + if (!SetReceivedFlags) + { + Debug.Assert(SocketAddress == null); + + ReceivedFlags = SocketFlags.None; + return SocketPal.TryCompleteReceive(context._socket, Buffer.Span, Flags, out BytesTransferred, out ErrorCode); + } + else + { + return SocketPal.TryCompleteReceiveFrom(context._socket, Buffer.Span, null, Flags, SocketAddress, ref SocketAddressLen, out BytesTransferred, out ReceivedFlags, out ErrorCode); + } } } @@ -1465,13 +1476,13 @@ public SocketError ConnectAsync(byte[] socketAddress, int socketAddressLen, Acti return SocketError.IOPending; } - public SocketError Receive(Memory buffer, ref SocketFlags flags, int timeout, out int bytesReceived) + public SocketError Receive(Memory buffer, SocketFlags flags, int timeout, out int bytesReceived) { int socketAddressLen = 0; return ReceiveFrom(buffer, ref flags, null, ref socketAddressLen, timeout, out bytesReceived); } - public SocketError Receive(Span buffer, ref SocketFlags flags, int timeout, out int bytesReceived) + public SocketError Receive(Span buffer, SocketFlags flags, int timeout, out int bytesReceived) { int socketAddressLen = 0; return ReceiveFrom(buffer, ref flags, null, ref socketAddressLen, timeout, out bytesReceived); @@ -1545,6 +1556,39 @@ public unsafe SocketError ReceiveFrom(Span buffer, ref SocketFlags flags, } } + public SocketError ReceiveAsync(Memory buffer, SocketFlags flags, out int bytesReceived, Action callback, CancellationToken cancellationToken = default) + { + SetNonBlocking(); + + SocketError errorCode; + int observedSequenceNumber; + if (_receiveQueue.IsReady(this, out observedSequenceNumber) && + SocketPal.TryCompleteReceive(_socket, buffer.Span, flags, out bytesReceived, out errorCode)) + { + return errorCode; + } + + BufferMemoryReceiveOperation operation = RentBufferMemoryReceiveOperation(); + operation.SetReceivedFlags = false; + operation.Callback = callback; + operation.Buffer = buffer; + operation.Flags = flags; + operation.SocketAddress = null; + operation.SocketAddressLen = 0; + + if (!_receiveQueue.StartAsyncOperation(this, operation, observedSequenceNumber, cancellationToken)) + { + bytesReceived = operation.BytesTransferred; + errorCode = operation.ErrorCode; + + ReturnOperation(operation); + return errorCode; + } + + bytesReceived = 0; + return SocketError.IOPending; + } + public SocketError ReceiveFromAsync(Memory buffer, SocketFlags flags, byte[]? socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, Action callback, CancellationToken cancellationToken = default) { SetNonBlocking(); @@ -1558,6 +1602,7 @@ public SocketError ReceiveFromAsync(Memory buffer, SocketFlags flags, byt } BufferMemoryReceiveOperation operation = RentBufferMemoryReceiveOperation(); + operation.SetReceivedFlags = true; operation.Callback = callback; operation.Buffer = buffer; operation.Flags = flags; @@ -1579,7 +1624,7 @@ public SocketError ReceiveFromAsync(Memory buffer, SocketFlags flags, byt return SocketError.IOPending; } - public SocketError Receive(IList> buffers, ref SocketFlags flags, int timeout, out int bytesReceived) + public SocketError Receive(IList> buffers, SocketFlags flags, int timeout, out int bytesReceived) { return ReceiveFrom(buffers, ref flags, null, 0, timeout, out bytesReceived); } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs index d2ca491a52ae9..99147f05a429c 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs @@ -128,7 +128,17 @@ internal unsafe SocketError DoOperationReceive(SafeSocketHandle handle, Cancella SocketError errorCode; if (_bufferList == null) { - errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, out flags, TransferCompletionCallback, cancellationToken); + // TCP has no out-going receive flags. We can use different syscalls which give better performance. + bool noReceivedFlags = _currentSocket!.ProtocolType == ProtocolType.Tcp; + if (noReceivedFlags) + { + errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, TransferCompletionCallback, cancellationToken); + flags = SocketFlags.None; + } + else + { + errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, out flags, TransferCompletionCallback, cancellationToken); + } } else { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs index 2c3fd57c279af..f174b732c2552 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs @@ -96,7 +96,29 @@ public static unsafe SocketError CreateSocket(AddressFamily addressFamily, Socke return errorCode; } - private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) + private static unsafe int SysReceive(SafeSocketHandle socket, SocketFlags flags, Span buffer, out Interop.Error errno) + { + int received = 0; + + fixed (byte* b = &MemoryMarshal.GetReference(buffer)) + { + errno = Interop.Sys.Receive( + socket, + b, + buffer.Length, + flags, + &received); + } + + if (errno != Interop.Error.SUCCESS) + { + return -1; + } + + return received; + } + + private static unsafe int SysReceive(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { Debug.Assert(socketAddress != null || socketAddressLen == 0, $"Unexpected values: socketAddress={socketAddress}, socketAddressLen={socketAddressLen}"); @@ -137,7 +159,30 @@ private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, Sp return checked((int)received); } - private static unsafe int Send(SafeSocketHandle socket, SocketFlags flags, ReadOnlySpan buffer, ref int offset, ref int count, byte[]? socketAddress, int socketAddressLen, out Interop.Error errno) + private static unsafe int SysSend(SafeSocketHandle socket, SocketFlags flags, ReadOnlySpan buffer, ref int offset, ref int count, out Interop.Error errno) + { + int sent; + fixed (byte* b = &MemoryMarshal.GetReference(buffer)) + { + errno = Interop.Sys.Send( + socket, + &b[offset], + count, + flags, + &sent); + } + + if (errno != Interop.Error.SUCCESS) + { + return -1; + } + + offset += sent; + count -= sent; + return sent; + } + + private static unsafe int SysSend(SafeSocketHandle socket, SocketFlags flags, ReadOnlySpan buffer, ref int offset, ref int count, byte[] socketAddress, int socketAddressLen, out Interop.Error errno) { int sent; fixed (byte* sockAddr = socketAddress) @@ -177,7 +222,7 @@ private static unsafe int Send(SafeSocketHandle socket, SocketFlags flags, ReadO return sent; } - private static unsafe int Send(SafeSocketHandle socket, SocketFlags flags, IList> buffers, ref int bufferIndex, ref int offset, byte[]? socketAddress, int socketAddressLen, out Interop.Error errno) + private static unsafe int SysSend(SafeSocketHandle socket, SocketFlags flags, IList> buffers, ref int bufferIndex, ref int offset, byte[]? socketAddress, int socketAddressLen, out Interop.Error errno) { // Pin buffers and set up iovecs. int startIndex = bufferIndex, startOffset = offset; @@ -274,7 +319,7 @@ private static unsafe long SendFile(SafeSocketHandle socket, SafeFileHandle file return bytesSent; } - private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, IList> buffers, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) + private static unsafe int SysReceive(SafeSocketHandle socket, SocketFlags flags, IList> buffers, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { int available = 0; errno = Interop.Sys.GetBytesAvailable(socket, &available); @@ -373,7 +418,7 @@ private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, IL return checked((int)received); } - private static unsafe int ReceiveMessageFrom(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) + private static unsafe int SysReceiveMessageFrom(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) { Debug.Assert(socketAddress != null, "Expected non-null socketAddress"); @@ -423,7 +468,7 @@ private static unsafe int ReceiveMessageFrom(SafeSocketHandle socket, SocketFlag return checked((int)received); } - private static unsafe int ReceiveMessageFrom( + private static unsafe int SysReceiveMessageFrom( SafeSocketHandle socket, SocketFlags flags, IList> buffers, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) @@ -617,6 +662,60 @@ public static unsafe bool TryCompleteConnect(SafeSocketHandle socket, int socket public static bool TryCompleteReceiveFrom(SafeSocketHandle socket, IList> buffers, SocketFlags flags, byte[]? socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, out SocketError errorCode) => TryCompleteReceiveFrom(socket, default(Span), buffers, flags, socketAddress, ref socketAddressLen, out bytesReceived, out receivedFlags, out errorCode); + public static unsafe bool TryCompleteReceive(SafeSocketHandle socket, Span buffer, SocketFlags flags, out int bytesReceived, out SocketError errorCode) + { + try + { + Interop.Error errno; + int received; + + if (buffer.Length == 0) + { + // Special case a receive of 0 bytes into a single buffer. A common pattern is to ReceiveAsync 0 bytes in order + // to be asynchronously notified when data is available, without needing to dedicate a buffer. Some platforms (e.g. macOS), + // however complete a 0-byte read successfully when data isn't available, as the request can logically be satisfied + // synchronously. As such, we treat 0 specially, and perform a 1-byte peek. + byte oneBytePeekBuffer; + received = SysReceive(socket, flags | SocketFlags.Peek, new Span(&oneBytePeekBuffer, 1), out errno); + if (received > 0) + { + // Peeked for 1-byte, but the actual request was for 0. + received = 0; + } + } + else + { + // Receive > 0 bytes into a single buffer + received = SysReceive(socket, flags, buffer, out errno); + } + + if (received != -1) + { + bytesReceived = received; + errorCode = SocketError.Success; + return true; + } + + bytesReceived = 0; + + if (errno != Interop.Error.EAGAIN && errno != Interop.Error.EWOULDBLOCK) + { + errorCode = GetSocketErrorForErrorCode(errno); + return true; + } + + errorCode = SocketError.Success; + return false; + } + catch (ObjectDisposedException) + { + // The socket was closed, or is closing. + bytesReceived = 0; + errorCode = SocketError.OperationAborted; + return true; + } + } + public static unsafe bool TryCompleteReceiveFrom(SafeSocketHandle socket, Span buffer, IList>? buffers, SocketFlags flags, byte[]? socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, out SocketError errorCode) { try @@ -627,7 +726,7 @@ public static unsafe bool TryCompleteReceiveFrom(SafeSocketHandle socket, Span(&oneBytePeekBuffer, 1), socketAddress, ref socketAddressLen, out receivedFlags, out errno); + received = SysReceive(socket, flags | SocketFlags.Peek, new Span(&oneBytePeekBuffer, 1), socketAddress, ref socketAddressLen, out receivedFlags, out errno); if (received > 0) { // Peeked for 1-byte, but the actual request was for 0. @@ -646,7 +745,7 @@ public static unsafe bool TryCompleteReceiveFrom(SafeSocketHandle socket, Span 0 bytes into a single buffer - received = Receive(socket, flags, buffer, socketAddress, ref socketAddressLen, out receivedFlags, out errno); + received = SysReceive(socket, flags, buffer, socketAddress, ref socketAddressLen, out receivedFlags, out errno); } if (received != -1) @@ -684,8 +783,8 @@ public static unsafe bool TryCompleteReceiveMessageFrom(SafeSocketHandle socket, Interop.Error errno; int received = buffers == null ? - ReceiveMessageFrom(socket, flags, buffer, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno) : - ReceiveMessageFrom(socket, flags, buffers, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno); + SysReceiveMessageFrom(socket, flags, buffer, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno) : + SysReceiveMessageFrom(socket, flags, buffers, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno); if (received != -1) { @@ -746,8 +845,9 @@ public static bool TryCompleteSendTo(SafeSocketHandle socket, ReadOnlySpan try { sent = buffers != null ? - Send(socket, flags, buffers, ref bufferIndex, ref offset, socketAddress, socketAddressLen, out errno) : - Send(socket, flags, buffer, ref offset, ref count, socketAddress, socketAddressLen, out errno); + SysSend(socket, flags, buffers, ref bufferIndex, ref offset, socketAddress, socketAddressLen, out errno) : + socketAddress == null ? SysSend(socket, flags, buffer, ref offset, ref count, out errno) : + SysSend(socket, flags, buffer, ref offset, ref count, socketAddress, socketAddressLen, out errno); } catch (ObjectDisposedException) { @@ -1009,12 +1109,12 @@ public static SocketError SendTo(SafeSocketHandle handle, byte[] buffer, int off return errorCode; } - public static SocketError Receive(SafeSocketHandle handle, IList> buffers, ref SocketFlags socketFlags, out int bytesTransferred) + public static SocketError Receive(SafeSocketHandle handle, IList> buffers, SocketFlags socketFlags, out int bytesTransferred) { SocketError errorCode; if (!handle.IsNonBlocking) { - errorCode = handle.AsyncContext.Receive(buffers, ref socketFlags, handle.ReceiveTimeout, out bytesTransferred); + errorCode = handle.AsyncContext.Receive(buffers, socketFlags, handle.ReceiveTimeout, out bytesTransferred); } else { @@ -1032,12 +1132,11 @@ public static SocketError Receive(SafeSocketHandle handle, byte[] buffer, int of { if (!handle.IsNonBlocking) { - return handle.AsyncContext.Receive(new Memory(buffer, offset, count), ref socketFlags, handle.ReceiveTimeout, out bytesTransferred); + return handle.AsyncContext.Receive(new Memory(buffer, offset, count), socketFlags, handle.ReceiveTimeout, out bytesTransferred); } - int socketAddressLen = 0; SocketError errorCode; - bool completed = TryCompleteReceiveFrom(handle, new Span(buffer, offset, count), socketFlags, null, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode); + bool completed = TryCompleteReceive(handle, new Span(buffer, offset, count), socketFlags, out bytesTransferred, out errorCode); return completed ? errorCode : SocketError.WouldBlock; } @@ -1045,12 +1144,11 @@ public static SocketError Receive(SafeSocketHandle handle, Span buffer, So { if (!handle.IsNonBlocking) { - return handle.AsyncContext.Receive(buffer, ref socketFlags, handle.ReceiveTimeout, out bytesTransferred); + return handle.AsyncContext.Receive(buffer, socketFlags, handle.ReceiveTimeout, out bytesTransferred); } - int socketAddressLen = 0; SocketError errorCode; - bool completed = TryCompleteReceiveFrom(handle, buffer, socketFlags, null, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode); + bool completed = TryCompleteReceive(handle, buffer, socketFlags, out bytesTransferred, out errorCode); return completed ? errorCode : SocketError.WouldBlock; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs index ed39e9be08b67..6ea3e1cc03aa2 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs @@ -338,7 +338,7 @@ public static unsafe SocketError SendTo(SafeSocketHandle handle, byte[] buffer, return SocketError.Success; } - public static SocketError Receive(SafeSocketHandle handle, IList> buffers, ref SocketFlags socketFlags, out int bytesTransferred) + public static SocketError Receive(SafeSocketHandle handle, IList> buffers, SocketFlags socketFlags, out int bytesTransferred) { const int StackThreshold = 16; // arbitrary limit to avoid too much space on stack (note: may be over-sized, that's OK - length passed separately) int count = buffers.Count;