Skip to content

Socket.SendFile(string, byte[], byte[], TransmitFileOptions) fails with null file path on Windows #42529

@stephentoub

Description

@stephentoub

The docs for Socket.SendFile, as well as the nullability annotations for the multi-arg overload, allow for SendFile to be passed a null file path, e.g. this succeeds on .NET Framework and on Linux/macOS on .NET Core:

using System.Net;
using System.Net.Sockets;

class Program
{
    static void Main()
    {
        var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
        listener.Listen(1);

        client.Connect(listener.LocalEndPoint);
        var server = listener.Accept();

        var buffer = new byte[1_000_000];
        client.SendFile(null, buffer, buffer, TransmitFileOptions.UseDefaultWorkerThread);

        int count = 0;
        while (count < buffer.Length * 2)
        {
            int received = server.Receive(buffer);
            count += received;
        }
    }
}

On .NET Core (both 3.1 and 5) on Windows, however, this throws:

Unhandled exception. System.ArgumentNullException: SafeHandle cannot be null. (Parameter 'pHandle')
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   at Interop.Mswsock.TransmitFile(SafeHandle socket, SafeHandle fileHandle, Int32 numberOfBytesToWrite, Int32 numberOfBytesPerSend, NativeOverlapped* overlapped, TransmitFileBuffers* buffers, TransmitFileOptions flags)
   at System.Net.Sockets.SocketPal.TransmitFileHelper(SafeHandle socket, SafeHandle fileHandle, NativeOverlapped* overlapped, Byte[] preBuffer, Byte[] postBuffer, TransmitFileOptions flags)
   at System.Net.Sockets.SocketPal.SendFile(SafeSocketHandle handle, SafeFileHandle fileHandle, Byte[] preBuffer, Byte[] postBuffer, TransmitFileOptions flags)
   at System.Net.Sockets.Socket.SendFileInternal(String fileName, Byte[] preBuffer, Byte[] postBuffer, TransmitFileOptions flags)
   at System.Net.Sockets.Socket.SendFile(String fileName, Byte[] preBuffer, Byte[] postBuffer, TransmitFileOptions flags)
   at System.Net.Sockets.Socket.SendFile(String fileName)
   at Program.Main()

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions