Sending Large Files Over A Network Socket Using C#

This article will explain how to send large files of any extension type and of any size over a network socket. The files would be sent as chunks of predetermined size, instead of sending them in one go. By sending large files as chunks, we will be able to calculate and report the progress of the file transfer. 

Note
For simplicity, this functionality is not implemented to run asynchronously. 

Read the file into FileStream

FileStream file = new FileStream(filePath, FileMode.Open);;
long totalBytes = file.Length, bytesSoFar = 0;

This will load the file from the file path into the FileStream and will show the length of the file to calculate the progress.

Initializing the Endpoint and Socket

IPEndPoint endpoint = new IPEndPoint(deviceAddr, 9100);
Socket sock = new Socket(deviceAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sock.SendTimeout = 1000000; //timeout in milliseconds
sock.Connect(endpoint);

Create an endpoint to the IP address of the network connected device and here the port used is 9100 (it can be any port). Initialize the Socket and assing the timeout value in milliseconds. 

Sock.Connect will establish a connection to the network socket over the specified port.

Convert the file into Chunks and send it over Socket

byte[] filechunk = new byte[4096];
int numBytes;
while ((numBytes = file.Read(filechunk, 0, 4096)) > 0) {
    if (sock.Send(filechunk, numBytes, SocketFlags.None) != numBytes) {
        throw new Exception("Error in sending the file");
    }
    bytesSoFar += numBytes;
    Byte progress = (byte)(bytesSoFar * 100 / totalBytes);
    if (progress > lastStatus && progress != 100) {
        Console.WriteLine("File sending progress:{0}", lastStatus);
        lastStatus = progress;
    }
}
sock.Shutdown(SocketShutdown.Both);

The above code will convert the file into chunks of size 4096 bytes and send it over the network socket. The progress of the file being transferred will be calculated and the progress will be displayed.

Finally, the Socket is shut down and the streams are closed.

Full code 

public bool SendFile(IPAddress deviceAddr, string filePath) {
    int lastStatus = 0;
    FileStream file = new FileStream(filePath, FileMode.Open);;
    long totalBytes = file.Length, bytesSoFar = 0;
    IPEndPoint endpoint = new IPEndPoint(deviceAddr, 9100);
    Socket sock = new Socket(deviceAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    sock.SendTimeout = 1000000; //timeout in milliseconds
    try {
        sock.Connect(endpoint);
        byte[] filechunk = new byte[4096];
        int numBytes;
        while ((numBytes = file.Read(filechunk, 0, 4096)) > 0) {
            if (sock.Send(filechunk, numBytes, SocketFlags.None) != numBytes) {
                throw new Exception("Error in sending the file");
            }
            bytesSoFar += numBytes;
            Byte progress = (byte)(bytesSoFar * 100 / totalBytes);
            if (progress > lastStatus && progress != 100) {
                Console.WriteLine("File sending progress:{0}", lastStatus);
                lastStatus = progress;
            }
        }
        sock.Shutdown(SocketShutdown.Both);
    } catch (SocketException e) {
        Console.WriteLine("Socket exception: {0}", e.Message.ToString());
        return false;
    } finally {
        sock.Close();
        file.Close();
    }
    return true;
}