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