BeginSendFile SocketException'参数不正确'

问题描述

我正在使用@H_404_1@BeginSendFile(filePath,socket)将文件发送到远程主机,它曾经可以工作,但是现在每当我尝试发送大文件(经过3 GB以上文件测试)时,我都再次访问该项目,我得到了{{ 1}}:

@H_404_1@SocketException

但是,小文件似乎没有触发异常(已测试

其他信息:Windows Defender和防火墙已禁用,并且计算机上没有AV。

这是我正在使用的代码

发件人:

@H_404_1@System.Net.sockets.socketException: 'The parameter is incorrect'

接收器:

@H_404_1@public static void SendFile(string dstIp,string filePath)
{
    // Establish the local endpoint for the socket.
    IPAddress ipAddr = IPAddress.Parse(dstIp);
    IPEndPoint ipEndPoint = new IPEndPoint(ipAddr,39993);

    // Create a TCP socket.
    Socket client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

    // Connect the socket to the remote endpoint.
    client.Connect(ipEndPoint);

    // Send the file
    client.BeginSendFile(@"C:\Users\username\Desktop\file.ext",SentFileCallback,client);
}

private static void SentFileCallback(IAsyncResult ar)
{
    var client = ar.AsyncState as Socket;

    // Complete sending the data to the remote device.
    client.EndSendFile(ar);

    // Release the socket.
    client.Shutdown(SocketShutdown.Both);
    client.Close();
}

解决方法

This answer 指出 SendFile 在下面使用 WinSock TransmitFile。 Its documentation 指出

使用一次对 TransmitFile 函数的调用可以传输的最大字节数为 2,147,483,646

作为一种解决方案,我最终使用 DotNetZip 在发送之前压缩和拆分大文件(如建议的 here):

int segmentsCreated;
using (ZipFile zip = new ZipFile())
{
   zip.AddDirectory(filePath);
   zip.MaxOutputSegmentSize = int.MaxValue - 1;
   zip.Save("bigFile.zip");

   segmentsCreated = zip.NumberOfSegmentsForMostRecentSave;
}

这会生成 bigFile.zip、bigFile.z01、bigFile.z02...,然后可以安全地使用 SendFile 方法将它们一一发送到客户端。