0

I want to send a File via sockets in C#. I am using a server and a client.

Server:

       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();
    }

Client:

   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);
    }

I mean How can Client know how many size the server is sending.

This is kinda simple since I just used it as a test.

But the server can only send files with sizes which are only about 10KB.

  • `new byte[10048]` -> `only about 10KB` - yeah, makes sense :) – Rand Random Sep 21 '18 at 07:56
  • You should change your buffer size or send many socket in a row. Btw duplicate of : https://stackoverflow.com/questions/34789423/sending-big-files-in-socket-programming-c-sharp – Benjamin K Sep 21 '18 at 07:57
  • How can client know how many KB or MB is sending? – AlirezaKamyab Sep 21 '18 at 08:04
  • It doesn't mind, just read until you get the end of the stream. Another solution can be to manually get your big file as binary and send many time the buffer size you want. Probably a good solution if you want to do a progress bar or have more control about it – Benjamin K Sep 21 '18 at 08:27
  • @AlirezaKamyab The server should inform the client how many bytes it will get. You could prefix the sending with a size. – Jeroen van Langen Sep 21 '18 at 08:30

2 Answers2

0

What you are probably running into is that the buffer for your client is full. Instead, try and use a stream to write the data to your disk.

NOTE: Untested code

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
    }
}

You probably also want to shut the socket properly to avoid partial data being sent using client.Shutdown(SocketShutdown.Both);

ikkentim
  • 1,639
  • 15
  • 30
0

I mean How can Client know how many size the server is sending.

Depends on what exactly you want to do. If you're only sending a single file and close the connection afterwards, that closing implies the end of the file. You'll simply loop over client.Receive() until it returns 0. A probably better solution would be to rely on a NetworkStream you can then do something like

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

But this will only work correctly when the server closes the client Socket when it's done sending.

If you want to transfer multiple files you'll have to use a protocol for the communication, a simple one would be to always send an int or long indicating the size of the file and then have the client read that amount of data.

Biesi
  • 800
  • 9
  • 17
  • Thanks, that was nice. – AlirezaKamyab Sep 21 '18 at 09:04
  • But A question, shall I shut the server down after sending a file via **socket.Sent**? or I should shut the server down after **_networkStream.CopyTo(fileStream);_** – AlirezaKamyab Sep 21 '18 at 09:11
  • @AlirezaKamyab you only need to close the `Socket` that you got from `listener.Accept`. If you want other clients to be able to connect to the server, don't shut it down. If it's only there to serve a single client, then shut it down afterwards. – Biesi Sep 21 '18 at 09:13