Dhivya Sadasivam
Dhivya Sadasivam

Reputation: 165

File transfer using Sockets

I need to transfer all type of files to a particular user based on his IPaddress and particular port.So whenever a new request comes at the specified port(the port where the servere is waiting for file) it means that a file is transferred,if its in another port some chat message is transferred.

My problem is i need to have the sent file name and size as well along with its content so that at the client side a new downloaded file will be created(with the same name) as the sent file.How can i go about this.Also i need to know the size of the file,so that i can create a byte array to receive the content.And my code is here.Please help me out

   public void fileClient()
        {
            TcpClient client = new TcpClient();
            client.Connect(IPAddress.Parse("127.0.0.1"), 40399);
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.ShowDialog();
            string fileName = dlg.FileName;
            FileInfo fi = new FileInfo(fileName);
            string fileNameandSize = fi.Name + "." + fi.Length;
            byte[] fileContents = File.ReadAllBytes(fileName);
                       Stream stream = client.GetStream();
              stream.SetLength(fi.Length);//If i set the file length here am getting an exception
                       stream.Write(fileContents, 0, fileContents.Length); 
            client.Close();
        }

public void fileServer()
    {
        TcpListener list;
        Int32 port1 = 40399;
        list = new TcpListener(port1);
        list.Start();
        TcpClient client = list.AcceptTcpClient();
        MessageBox.Show("Client trying to connect");
        Thread.Sleep(10);
            Stream stream = client.GetStream();
        byte[] receivedBytes = new byte[stream.Length];
        stream.Read(receivedBytes, 0, Convert.ToInt16(stream.Length));  
                   string fileName = "C:\\Users\\dhivya.s\\Desktop\\Recent received";
                    File.WriteAllBytes(fileName + "\\" + "newFile", receivedBytes);
        list.Stop();
        client.Close();
    }

Upvotes: 4

Views: 17493

Answers (2)

Ceelie
Ceelie

Reputation: 241

Without any checking, this seems to work. You can add checksums etc., decode the b64 save the file.

public class FileTransfer
{
    public string Name;
    public int Size;
    public string Content;
}

Send:

FileTransfer fileTransfer = new FileTransfer();
fileTransfer.Name = "TestFile";
fileTransfer.Content = System.Convert.ToBase64String(File.ReadAllBytes("c:\\data\\test.html"));
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(fileTransfer.GetType());
TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse("127.0.0.1"), 40399);
Stream stream = client.GetStream();
x.Serialize(stream, fileTransfer);
client.Close();

Rec:

TcpListener list;
Int32 port1 = 40399;
list = new TcpListener(port1);
list.Start();
TcpClient client = list.AcceptTcpClient();
Console.WriteLine("Client trying to connect");
Stream stream = client.GetStream();
XmlSerializer mySerializer = new XmlSerializer(typeof(FileTransfer));
FileTransfer myObject = (FileTransfer)mySerializer.Deserialize(stream);
Console.WriteLine("name: " + myObject.Name);
list.Stop();
client.Close();

Upvotes: 2

David Arno
David Arno

Reputation: 43264

File transfers like this rely on there being an agreed protocol between the end ends. For example you could define a simple protocol whereby the first four bytes specify the size of the file name, the next four the size of the file. Then send the file name, then the content. Then all you have to worry about is whether both ends of the wire use either big or little endian. If they are the same, you're fine.

This is why sockets aren't often a good choice for communications. There are plenty of existing protocols for transferring files (HTTP, FTP, AMF etc), which already handle this stuff for you. So why not use one of them?

Upvotes: 2

Related Questions