通过Socket.SendFile发送大文件

时间:2018-09-21 07:54:03

标签: c# sockets

我想通过C#中的套接字发送文件。我正在使用服务器和客户端。

服务器

       static void Main(string[] args)
    {
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 100));
        server.Listen(0);
        Socket client = server.Accept();
        client.SendFile("F:\\TestMovie.mp4");
        server.Close();
        Console.ReadKey();
    }

客户

   static void Main(string[] args)
    {
        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 100));

        byte[] buff = new byte[10048];
        int index = client.Receive(buff);

        if (buff.Length < index)
        {
            Array.Resize<byte>(ref buff, index);
        }

        File.WriteAllBytes("F:\\TestMovie.mp4", buff);
    }
  

我的意思是客户端如何知道服务器正在发送多少大小。

这有点简单,因为我只是将其用作测试。

但是服务器只能发送大小约为10KB的文件。

2 个答案:

答案 0 :(得分:0)

您可能遇到的问题是客户端的缓冲区已满。相反,请尝试使用流将数据写入磁盘。

注意:未经测试的代码

using(var stream = File.OpenWrite("path"))
{
    byte[] buff = new byte[2048];
    int read;

    try
    {
        do
        {
            read = client.Receive(buff);
            stream.Write(buff, 0, read);
        } while(read > 0);
    }
    catch(SocketException)
    {
        // exception is thrown when the socket was closed
    }
}

您可能还想正确关闭套接字,以避免使用client.Shutdown(SocketShutdown.Both);

发送部分数据

答案 1 :(得分:0)

  

我的意思是客户端如何知道服务器正在发送多少大小。

取决于您要确切执行的操作。如果您仅发送单个文件并随后关闭连接,则该关闭表示文件结束。您只需在client.Receive()上循环,直到返回0。 一个可能更好的解决方案是依靠NetworkStream进行类似

的操作
using (NetworkStream networkStream = new NetworkStream(client))
using (FileStream fileStream = File.Open("test.mp4", FileMode.OpenOrCreate))
{
    networkStream.CopyTo(fileStream);
}

但这仅在服务器完成发送后关闭服务器Socket时才能正常工作。

如果要传输多个文件,则必须使用一种协议进行通信,一个简单的方法是始终发送指示文件大小的intlong,然后让客户端读取该数量的数据。