File transfers through networks and the Internet

This tutorial will teach you how to send and receive files from your local system to a server, either through a network or through the Internet, using C# and streaming connections. This tutorial is also helpful for learning the basics of networking using the .NET Framework.

In this tutorial we’re going to build a very interesting .NET application, and based on the code here you will hopefully be able to build various applications or to help you with extending your current work.

Before digging into the code, you should know that the code you see in this tutorial and in the attached project resumes to only the strict functionality of exchanging files between two computers using the .NET Framework. If you want to integrate this into a real-life application, you will need to put more effort into this code since currently it lacks crash prevention and recovery, testing on multiple systems, against firewalls, etc.
For using this code I recommend that you use two different computers, either on a network or on the Internet. The firewall on both computers (but especially on the server computer) should be shut down to prevent the port we’re going to use being locked. However, the beauty of this application is that you can use a single computer to test it; you can run the server and the client application on the same computer and transfer files from one path to another.
Speaking of server and client, in this tutorial we’re going to build two applications. One is the server that listens for connections on a certain port and receives files in streams and then saves them to the local C:\ drive, and one is the client that connects to the server application on the same port the server is listening to.

The application is developed using .NET Framework 2.0 in Visual Studio 2005, however you should be able to convert it to .NET Framework 1.1 rather easily.

How the file transfer works

First we need to create the server application. The server application pictured below under the arrow will be the one receiving a file from a remote computer and storing it on the hard drive. Prior to receiving the actual file, it will receive information about the file: the file name and size. This information will be passed by the client, and it will be retrievied using the FileInfo class from the .NET Framework.

The first thing you need to do is to enter a port (815 is normally not taken on most computers) and click on “Start Server”. You will see a message “Starting the server…” shortly followed by “The server has started. Please connect the client to 192.168.0.1”. Of course, the IP will probably differ in your case, so you should write it down because you will need to enter it in the client application later. At this time you should leave the server application running and switch to the client application (Network File Sender).

The client application will first need to connect to the server, so you need to press the “Connect” button. Before pressing the button however, please make sure that you entered the same port as in the server window, and the IP that you were prompted to enter.
Hopefully you will not experience any problems and you will see the “Successfully connected to server” message. After that you will be able to press the “Send New File” button which will let you browse to a file. Right after you pick the file, you will see that the progress bar on the server (Network File Receiver) starts making progress and the file is being transfered. So where is the file? By default the code saves it to C:\ so look for it there. After the file is sent the client and server-side streams and connections are closed to release resources. To prepare for an upcoming connection, the server then starts again (of course, you can change this to your liking).

Receiving the file – creating the server

We will start with creating the server, since we first need an application to listen for connections before we actually send a file.
Begin by creating a new Windows Application project in Visual Studio 2005. Add to it two textboxes: txtPort stores the port that we are listening to, and txtLog will be the MultiLine textbox to which we will append text containing the status of the server. Add two buttons: btnStart and btnStop which are self explanatory, and finally a progress bar entitled prgDownload where we will display the progress of the file being transfered.

Switch to the code view and make sure you add these 4 additional using statements:

using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

Next we need to create some objects we’ll be setting and accessing throughout the application:

// The thread in which the file will be received
private Thread thrDownload;
// The stream for writing the file to the hard-drive
private Stream strLocal;
// The network stream that receives the file
private NetworkStream strRemote;
// The TCP listener that will listen for connections
private TcpListener tlsServer;
// Delegate for updating the logging textbox
private delegate void UpdateStatusCallback(string StatusMessage);
// Delegate for updating the progressbar
private delegate void UpdateProgressCallback(Int64 BytesRead, Int64 TotalBytes);
// For storing the progress in percentages
private static int PercentProgress;

Now we need to create the most important part of the application – the StartReceiving() method which listens and establishes connections with the client, and also receives the files. This method will be called from a thread, the thrDownload thread we defined above.

private void StartReceiving()
{
 // There are many lines in here that can cause an exception
try
{
// Get the hostname of the current computer (the server)
string hstServer = Dns.GetHostName();
// Get the IP of the first network device, however this can prove unreliable on certain configurations
IPAddress ipaLocal = Dns.GetHostEntry(hstServer).AddressList[0];
// If the TCP listener object was not created before, create it
if (tlsServer == null)
{
 // Create the TCP listener object using the IP of the server and the specified port
tlsServer = new TcpListener(ipaLocal, Convert.ToInt32(txtPort.Text));
}

        // Write the status to the log textbox on the form (txtLog)
this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “Starting the server…\r\n” });
// Start the TCP listener and listen for connections
tlsServer.Start();
// Write the status to the log textbox on the form (txtLog)
this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The server has started. Please connect the client to “ + ipaLocal.ToString() + “\r\n” });

        // Accept a pending connection

        TcpClient tclServer = tlsServer.AcceptTcpClient();

        // Write the status to the log textbox on the form (txtLog)

        this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The server has accepted the client\r\n” });

        // Receive the stream and store it in a NetworkStream object

        strRemote = tclServer.GetStream();

        // Write the status to the log textbox on the form (txtLog)

        this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The server has received the stream\r\n” });

        // For holding the number of bytes we are reading at one time from the stream

        int bytesSize = 0;

        // The buffer that holds the data received from the client

        byte[] downBuffer = new byte[2048];

        // Read the first buffer (2048 bytes) from the stream – which represents the file name

        bytesSize = strRemote.Read(downBuffer, 0, 2048);

        // Convert the stream to string and store the file name

        string FileName = System.Text.Encoding.ASCII.GetString(downBuffer, 0, bytesSize);

        // Set the file stream to the path C:\ plus the name of the file that was on the sender’s computer

        strLocal = new FileStream(@”C:\” + FileNameFileMode.Create, FileAccess.Write, FileShare.ReadWrite);

        // The buffer that holds the data received from the client

        downBuffer = new byte[2048];

        // Read the next buffer (2048 bytes) from the stream – which represents the file size

        bytesSize = strRemote.Read(downBuffer, 0, 2048);

        // Convert the file size from bytes to string and then to long (Int64)

        long FileSize = Convert.ToInt64(System.Text.Encoding.ASCII.GetString(downBuffer, 0, bytesSize));

        // Write the status to the log textbox on the form (txtLog)

        this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “Receiving file “ + FileName + ” (” + FileSize + ” bytes)\r\n” });

        // The buffer size for receiving the file

        downBuffer = new byte[2048];

        // From now on we read everything that’s in the stream’s buffer because the file content has started

        while ((bytesSize = strRemote.Read(downBuffer, 0, downBuffer.Length)) > 0)

        {

            // Write the data to the local file stream

            strLocal.Write(downBuffer, 0, bytesSize);

            // Update the progressbar by passing the file size and how much we downloaded so far to UpdateProgress()

            this.Invoke(new UpdateProgressCallback(this.UpdateProgress), new object[] { strLocal.Length, FileSize });

        }

        // When this point is reached, the file has been received and stored successfully

    }

    finally

    {

        // This part of the method will fire no matter wether an error occured in the above code or not

        // Write the status to the log textbox on the form (txtLog)

        this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The file was received. Closing streams.\r\n” });

        // Close the streams

        strLocal.Close();

        strRemote.Close();

        // Write the status to the log textbox on the form (txtLog)

        this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “Streams are now closed.\r\n” });

        // Start the server (TCP listener) all over again

        StartReceiving();

    }

}

If you are not used to networking with .NET applications, or if you have only started C# recently you may have found the above code a little overwhelming. If so, you may find the Creating a download manage in C# tutorial I created a short while back, to be more helpful for a beginner, since it has explanations on why we are using delegates to update the form from a thread, and how the streams and buffers work.

In case you are wondering why we are reading the data stream two times, 2048 bytes at a time and then we are suddenly looping through all the data using a while loop in the code above, here is why: in the client application that we are going to build, we will first send the file name within the first 2048 bytes to the server, using the same stream we will be using for transfering the actual file. Thus, first we only read the first 2048 bytes and store then in the FileName variable because the client application will send the file name within the first 2048 bytes. Then we repeat the same thing for transfering the size of the file – we read the second set of 2048 bytes which contain the file size and store this into the FileSize variable. We need to know the file name so that on the server we can save the file using the same file name as it was in the client (this includes the extension); as for the file size, we want to know that so that we can calculate the current progress of the download.
After we pass this, there is no other data coming in the stream other than the file itself, so we loop through the stream until we reach the end, and we continue writing 2048 bytes of the file at a time on the server computer.

The next method we need to implement is the one we created a delegate for – UpdateStatus() which updates the txtLog textbox with the current status of the application:

private void UpdateStatus(string StatusMessage)

{
    // Append the status to the log textbox text

    txtLog.Text += StatusMessage;

}
There is one more method we created a delegate for, which is also accessed from inside the thread. This method updates the progress bar with the current progress of the download:

private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)

{

    if (TotalBytes > 0)

    {

        // Calculate the download progress in percentages

        PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);

        // Make progress on the progress bar

        prgDownload.Value = PercentProgress;

    }

}
Now there’s one more important thing left to do – start the thread with the StartReceiving() method, all inside the btnStart click event. To create the Click event of this button you can double click it in form designer view. Inside it, add the following code:

thrDownload = new Thread(StartReceiving);

thrDownload.Start();
You will probably also want to close the streams using the btnStop button, so click this button and add the following code:

strLocal.Close();

strRemote.Close();

txtLog.Text += “Streams are now closed.\r\n”;
That is all, you now have a C# server ready to listen for connections and receive files. Below is the entire code for this application in case you prefer an overall look:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.IO;

using System.Threading;

namespace NetworkFileReceiver

{

    public partial class Form1 Form

    {

        // The thread in which the file will be received

        private Thread thrDownload;

        // The stream for writing the file to the hard-drive

        private Stream strLocal;

        // The network stream that receives the file

        private NetworkStream strRemote;

        // The TCP listener that will listen for connections

        private TcpListener tlsServer;

        // Delegate for updating the logging textbox

        private delegate void UpdateStatusCallback(string StatusMessage);

        // Delegate for updating the progressbar

        private delegate void UpdateProgressCallback(Int64 BytesRead, Int64 TotalBytes);

        // For storing the progress in percentages

        private static int PercentProgress;

        public Form1()

        {

            InitializeComponent();

        }

        private void btnStart_Click(object sender, EventArgs e)

        {

            thrDownload = new Thread(StartReceiving);

            thrDownload.Start();

        }

        private void StartReceiving()

        {

            // There are many lines in here that can cause an exception

            try

            {

                // Get the hostname of the current computer (the server)

                string hstServer = Dns.GetHostName();

                // Get the IP of the first network device, however this can prove unreliable on certain configurations

                IPAddress ipaLocal = Dns.GetHostEntry(hstServer).AddressList[0];

                // If the TCP listener object was not created before, create it

                if (tlsServer == null)

                {

                    // Create the TCP listener object using the IP of the server and the specified port

                    tlsServer = new TcpListener(ipaLocal, Convert.ToInt32(txtPort.Text));

                }

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “Starting the server…\r\n” });

                // Start the TCP listener and listen for connections

                tlsServer.Start();

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The server has started. Please connect the client to “ + ipaLocal.ToString() + “\r\n” });

                // Accept a pending connection

                TcpClient tclServer = tlsServer.AcceptTcpClient();

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The server has accepted the client\r\n” });

                // Receive the stream and store it in a NetworkStream object

                strRemote = tclServer.GetStream();

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The server has received the stream\r\n” });

                // For holding the number of bytes we are reading at one time from the stream

                int bytesSize = 0;

                // The buffer that holds the data received from the client

                byte[] downBuffer = new byte[2048];

                // Read the first buffer (2048 bytes) from the stream – which represents the file name

                bytesSize = strRemote.Read(downBuffer, 0, 2048);

                // Convert the stream to string and store the file name

                string FileName = System.Text.Encoding.ASCII.GetString(downBuffer, 0, bytesSize);

                // Set the file stream to the path C:\ plus the name of the file that was on the sender’s computer

                strLocal = new FileStream(@”C:\” + FileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

                // The buffer that holds the data received from the client

                downBuffer = new byte[2048];

                // Read the next buffer (2048 bytes) from the stream – which represents the file size

                bytesSize = strRemote.Read(downBuffer, 0, 2048);

                // Convert the file size from bytes to string and then to long (Int64)

                long FileSize = Convert.ToInt64(System.Text.Encoding.ASCII.GetString(downBuffer, 0, bytesSize));

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “Receiving file “ + FileName + ” (“ + FileSize + ” bytes)\r\n” });

                // The buffer size for receiving the file

                downBuffer = new byte[2048];

                // From now on we read everything that’s in the stream’s buffer because the file content has started

                while ((bytesSize = strRemote.Read(downBuffer, 0, downBuffer.Length)) > 0)

                {

                    // Write the data to the local file stream

                    strLocal.Write(downBuffer, 0, bytesSize);

                    // Update the progressbar by passing the file size and how much we downloaded so far to UpdateProgress()

                    this.Invoke(new UpdateProgressCallback(this.UpdateProgress), new object[] { strLocal.Length, FileSize });

                }

                // When this point is reached, the file has been received and stored successfuly

            }

            finally

            {

                // This part of the method will fire no matter wether an error occured in the above code or not

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “The file was received. Closing streams.\r\n” });

                // Close the streams

                strLocal.Close();

                strRemote.Close();

                // Write the status to the log textbox on the form (txtLog)

                this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { “Streams are now closed.\r\n” });

                // Start the server (TCP listener) all over again

                StartReceiving();

            }

        }

        private void UpdateStatus(string StatusMessage)

        {

            // Append the status to the log textbox text

            txtLog.Text += StatusMessage;

        }

        private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)

        {

            if (TotalBytes > 0)

            {

                // Calculate the download progress in percentages

                PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);

                // Make progress on the progress bar

                prgDownload.Value = PercentProgress;

            }

        }

        private void btnStop_Click(object sender, EventArgs e)

        {

            strLocal.Close();

            strRemote.Close();

            txtLog.Text += “Streams are now closed.\r\n”;

        }

    }

}
You should now compile and run this application. If everything appears to work fine, your next move is creating the file sender application:

Sending the file – creating the client

Start another Windows Application project in Visual Studio 2005 and add to it 3 textboxes and 3 buttons. The textboxes are: txtPorttxtServer and txtLog. The buttons are btnConnectbtnDisconnect and btnSend. Similar to what we did in the server application, you will need to switch to code view and add the following using statements:

using System.Net;
using System.Net.Sockets;
using System.IO;


Follow by defining the following objects inside the class:

// The TCP client will connect to the server using an IP and a port

TcpClient tcpClient;

// The file stream will read bytes from the local file you are sending

FileStream fstFile;

// The network stream will send bytes to the server application

NetworkStream strRemote;
Before sending a file we need to establish a successful connection to the server. Inside the application’s class we’re going to build a small method that does just that:

private void ConnectToServer(string ServerIP, int ServerPort)

{

    // Create a new instance of a TCP client

    tcpClient = new TcpClient();

    try

    {

        // Connect the TCP client to the specified IP and port

        tcpClient.Connect(ServerIP, ServerPort);

        txtLog.Text += “Successfully connected to server\r\n”;

    }

    catch (Exception exMessage)

    {

        // Display any possible error

        txtLog.Text += exMessage.Message;

    }

}
Now we’re going to call this method from the click event of btnConnect, so double click the button in design view so that you get the Click event automatically created, then inside it place the following code:

// Call the ConnectToServer method and pass the parameters entered by the user

ConnectToServer(txtServer.Text, Convert.ToInt32(txtPort.Text));
At this point if you open the server application we created and set it to monitor on port 815, then run the client application and press the btnConnect button, you should see in the server application window how the connection is accepted.

Moving on, we haven’t yet seen the code that actually sends the file to the server. We want to have this code inside the Click event of btnSend, thus double click that button and inside the event use the following chunk of code:

// If tclClient is not connected, try a connection

if (tcpClient.Connected == false)

{

    // Call the ConnectToServer method and pass the parameters entered by the user

    ConnectToServer(txtServer.Text, Convert.ToInt32(txtPort.Text));

}

// Prompt the user for opening a file

if (openFile.ShowDialog() == DialogResult.OK)

{

    txtLog.Text += “Sending file information\r\n”;

    // Get a stream connected to the server

    strRemote = tcpClient.GetStream();

    byte[] byteSend = new byte[tcpClient.ReceiveBufferSize];

    // The file stream will read bytes from the file that the user has chosen

    fstFile = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read);

    // Read the file as binary

    BinaryReader binFile = new BinaryReader(fstFile);

    // Get information about the opened file

    FileInfo fInfo = new FileInfo(openFile.FileName);

    // Get and store the file name

    string FileName = fInfo.Name;

    // Store the file name as a sequence of bytes

    byte[] ByteFileName = new byte[2048];

    ByteFileName = System.Text.Encoding.ASCII.GetBytes(FileName.ToCharArray());

    // Write the sequence of bytes (the file name) to the network stream

    strRemote.Write(ByteFileName, 0, ByteFileName.Length);

    // Get and store the file size

    long FileSize = fInfo.Length;

    // Store the file size as a sequence of bytes

    byte[] ByteFileSize = new byte[2048];

    ByteFileSize = System.Text.Encoding.ASCII.GetBytes(FileSize.ToString().ToCharArray());

    // Write the sequence of bytes (the file size) to the network stream

    strRemote.Write(ByteFileSize, 0, ByteFileSize.Length);

    txtLog.Text += “Sending the file “ + FileName + ” (“ + FileSize + ” bytes)\r\n”;

    // Reset the number of read bytes

    int bytesSize = 0;

    // Define the buffer size

    byte[] downBuffer = new byte[2048];

    // Loop through the file stream of the local file

    while ((bytesSize = fstFile.Read(downBuffer, 0, downBuffer.Length)) > 0)

    {

        // Write the data that composes the file to the network stream

        strRemote.Write(downBuffer, 0, bytesSize);

    }

    // Update the log textbox and close the connections and streams

    txtLog.Text += “File sent. Closing streams and connections.\r\n”;

    tcpClient.Close();

    strRemote.Close();

    fstFile.Close();

    txtLog.Text += “Streams and connections are now closed.\r\n”;

}
As you can see here, using the stream we are first sending to the server the file name; the server on its side will read this piece of stream and store the file name in a variable for later use. Same happens for the file size, which is retrieved just like the file name using the FileInfo class and written to the stream. After we send these two pices of information, we start sending the actual content of the file (in binary). The content is sent by looping through yet another stream – the file stream, a local stream that reads the file from the hard drive. While we read pieces of this local stream we write pieces to the network stream so that the server can receive them and save them, until the very last byte of the file when the while loop ends.
After that the streams and connections are closed, and the client has received the file.

There’s one more piece of this application that we haven’t implemented yet, the disconnection from the server. This happens when btnDisconnect is clicked:

// Close connections and streams and update the log textbox

tcpClient.Close();

strRemote.Close();

fstFile.Close();

txtLog.Text += “Disconnected from server.\r\n”;
We’re pretty much finished with this tutorial. I hope you enjoyed it and didn’t experience too many problems with using this code on your system.
Below is the complete code of the network file sender application (the client):

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.IO;

namespace NetworkFileSender

{

    public partial class Form1 Form

    {

        // The TCP client will connect to the server using an IP and a port

        TcpClient tcpClient;

        // The file stream will read bytes from the local file you are sending

        FileStream fstFile;

        // The network stream will send bytes to the server application

        NetworkStream strRemote;

        public Form1()

        {

            InitializeComponent();

        }

        private void ConnectToServer(string ServerIP, int ServerPort)

        {

            // Create a new instance of a TCP client

            tcpClient = new TcpClient();

            try

            {

                // Connect the TCP client to the specified IP and port

                tcpClient.Connect(ServerIP, ServerPort);

                txtLog.Text += “Successfully connected to server\r\n”;

            }

            catch (Exception exMessage)

            {

                // Display any possible error

                txtLog.Text += exMessage.Message;

            }

        }

        private void btnConnect_Click(object sender, EventArgs e)

        {

            // Call the ConnectToServer method and pass the parameters entered by the user

            ConnectToServer(txtServer.Text, Convert.ToInt32(txtPort.Text));

        }

        private void btnSend_Click(object sender, EventArgs e)

        {

            // If tclClient is not connected, try a connection

            if (tcpClient.Connected == false)

            {

                // Call the ConnectToServer method and pass the parameters entered by the user

                ConnectToServer(txtServer.Text, Convert.ToInt32(txtPort.Text));

            }

            // Prompt the user for opening a file

            if (openFile.ShowDialog() == DialogResult.OK)

            {

                txtLog.Text += “Sending file information\r\n”;

                // Get a stream connected to the server

                strRemote = tcpClient.GetStream();

                byte[] byteSend = new byte[tcpClient.ReceiveBufferSize];

                // The file stream will read bytes from the file that the user has chosen

                fstFile = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read);

                // Read the file as binary

                BinaryReader binFile = new BinaryReader(fstFile);

                // Get information about the opened file

                FileInfo fInfo = new FileInfo(openFile.FileName);

                // Get and store the file name

                string FileName = fInfo.Name;

                // Store the file name as a sequence of bytes

                byte[] ByteFileName = new byte[2048];

                ByteFileName = System.Text.Encoding.ASCII.GetBytes(FileName.ToCharArray());

                // Write the sequence of bytes (the file name) to the network stream

                strRemote.Write(ByteFileName, 0, ByteFileName.Length);

                // Get and store the file size

                long FileSize = fInfo.Length;

                // Store the file size as a sequence of bytes

                byte[] ByteFileSize = new byte[2048];

                ByteFileSize = System.Text.Encoding.ASCII.GetBytes(FileSize.ToString().ToCharArray());

                // Write the sequence of bytes (the file size) to the network stream

                strRemote.Write(ByteFileSize, 0, ByteFileSize.Length);

                txtLog.Text += “Sending the file “ + FileName + ” (“ + FileSize + ” bytes)\r\n”;

                // Reset the number of read bytes

                int bytesSize = 0;

                // Define the buffer size

                byte[] downBuffer = new byte[2048];

                // Loop through the file stream of the local file

                while ((bytesSize = fstFile.Read(downBuffer, 0, downBuffer.Length)) > 0)

                {

                    // Write the data that composes the file to the network stream

                    strRemote.Write(downBuffer, 0, bytesSize);

                }

                // Update the log textbox and close the connections and streams

                txtLog.Text += “File sent. Closing streams and connections.\r\n”;

                tcpClient.Close();

                strRemote.Close();

                fstFile.Close();

                txtLog.Text += “Streams and connections are now closed.\r\n”;

            }

        }

        private void btnDisconnect_Click(object sender, EventArgs e)

        {

            // Close connections and streams and update the log textbox

            tcpClient.Close();

            strRemote.Close();

            fstFile.Close();

            txtLog.Text += “Disconnected from server.\r\n”;

        }

    }

}

Nathan Pakovskie is an esteemed senior developer and educator in the tech community, best known for his contributions to Geekpedia.com. With a passion for coding and a knack for simplifying complex tech concepts, Nathan has authored several popular tutorials on C# programming, ranging from basic operations to advanced coding techniques. His articles, often characterized by clarity and precision, serve as invaluable resources for both novice and experienced programmers. Beyond his technical expertise, Nathan is an advocate for continuous learning and enjoys exploring emerging technologies in AI and software development. When he’s not coding or writing, Nathan engages in mentoring upcoming developers, emphasizing the importance of both technical skills and creative problem-solving in the ever-evolving world of technology. Specialties: C# Programming, Technical Writing, Software Development, AI Technologies, Educational Outreach

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top