c# - C#异步Socket.BeginSendFile仅发送两个异步文件

标签 c# .net sockets asyncsocket

我不知道为什么我的 Socket.BeginSendFile 一次只能发送两个文件。我在不同的计算机上测试了相同的结果。

Socket.BeginSend 似乎一次发送了所有三个。

我测试了将三个客户端连接到服务器。效果很好,所有三个都按预期连接异步。每个客户端(图片中的Test100.exe,Test200.exe,Test300.exe)将根据服务器所连接的客户端从服务器名为100、200或300的文件夹中请求文件。

问题是 Socket.BeginSendFile 一次最多只向流发送两个文件。一旦两个以前称为的Socket.BeginSendFile 中的一个完成。见下文;

前两个客户端之一发送完成发送后,第三个客户端就开始接收。

在代码中添加一些断点,我可以确定所有三个Socket.BeginSendFile(...)都被称为异步。

    private static void Send(Socket handler, String data)
    {
        string dateFolder =  data.Replace("<EOF>", "");

        string longFileName = "C:\\"+dateFolder+"\\poopoo.txt";
        string shortFileName = "poopoo.txt";

        // ==== for beginSend
        //byte[] fileData = File.ReadAllBytes(longFileName);
        // ==== for beginSend


        byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
        byte[] fileInfo = Encoding.ASCII.GetBytes("C:\\Users\\Trim\\Desktop");
        byte[] fileInfoLen = BitConverter.GetBytes(fileInfo.Length); // we know these are ints (4bytes)

        byte[] clientData = new byte[4 + fileNameByte.Length + fileInfoLen.Length + fileInfo.Length];// + fileData.Length + eofByte.Length
        // ==== for beginSend
        //byte[] clientData = new byte[4 + fileNameByte.Length + fileInfoLen.Length + fileInfo.Length + fileData.Length];
        // ==== for beginSend

        byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); // we know these are int (4bytes);

        fileNameLen.CopyTo(clientData, 0);
        fileNameByte.CopyTo(clientData, 4); // room for error file name 4bytes?
        fileInfoLen.CopyTo(clientData, 4 + fileNameByte.Length);
        fileInfo.CopyTo(clientData, 4 + fileNameByte.Length + fileInfoLen.Length);

        // ==== for beginSend
        //fileData.CopyTo(clientData, 4 + fileNameByte.Length + fileInfoLen.Length + fileInfo.Length);
        // ==== for beginSend
        // *** Break point shows all three being called async
        handler.BeginSendFile(longFileName, clientData, null, 0, new AsyncCallback(AsynchronousFileSendCallback), handler);



       // handler.BeginSend(clientData, 0, clientData.Length, 0, new AsyncCallback(SendCallback), handler);


    }

直到前两个AsynchronousFileSendCallback方法之一开始,第三个Socket.BeginSendFile(...)才真正开始发送文件。
    private static void AsynchronousFileSendCallback(IAsyncResult ar)
    {
        // Retrieve the socket from the state object.
        Socket client = (Socket)ar.AsyncState;

        // Complete sending the data to the remote device.
        client.EndSendFile(ar); // **Third** client doesn't actually start receiving his data until EndSendFile is called atleast once.

        Console.WriteLine("Send file to client.");
       // sendDone.Set();
        client.Shutdown(SocketShutdown.Both);
        client.Close();
    }

就像我之前说的,如果我使用 Socket.BeginSend ,问题就解决了。尽管我需要能够使用 Socket.BeginSendFile ,因为它在单独的线程上对文件进行分块,尤其是与我的 Socket一起使用的这行代码byte[] fileData = File.ReadAllBytes(longFileName);。BeginSend结构对于大文件是 Not Acceptable :(

非常感谢您的宝贵时间!

最佳答案

BeginSendFile很可能使用Windows API函数TransmitFile来完成其工作。并且此API限于Windows客户端版本上的2个并发传输。

Workstation and client versions of Windows optimize the TransmitFile function for minimum memory and resource utilization by limiting the number of concurrent TransmitFile operations allowed on the system to a maximum of two. On Windows Vista, Windows XP, Windows 2000 Professional, and Windows NT Workstation 3.51 and later only two outstanding TransmitFile requests are handled simultaneously; the third request will wait until one of the previous requests is completed.

关于c# - C#异步Socket.BeginSendFile仅发送两个异步文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14608508/

相关文章:

c# - 在 C# 中实现 De Boor 样条算法

c# - 将 FileStream 中的数据读入通用 Stream

c# - 获取 Repeater 的元素

.NET - WinForm 文本框 - Focus 和 SelectedText

.Net CIL jmp 操作码和泛型方法

c++ - Boost Asio 网络发送/接收是否有任何类型的数据完整性保证?

c - 后台线程上的多线程 TCP 服务器 - 如何强制从主线程关闭

c - 套接字:为什么阻塞 read() 因 ENOTCONN 而失败?

c# - 在数据表上使用通用列表会减少性能开销吗?

c# - 通过本地主机服务器在 asp.net 中发送电子邮件