使用套接字进行文件传输

4
我需要根据特定的IP地址和端口向特定用户传输所有类型的文件。因此,每当在指定端口(服务器等待文件的端口)收到新的请求时,就意味着已经传输了一个文件,如果在另一个端口,则传输了一些聊天消息。
我的问题是,我需要同时获取发送文件的名称和大小以及其内容,以便在客户端创建一个新的下载文件与发送文件具有相同的名称。如何处理这个问题?另外,我需要知道文件的大小,这样我才能创建一个字节数组来接收内容。以下是我的代码,请帮我解决这个问题。
   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();
    }

它们如何相互通信以告知彼此正在发生的事情。虽然套接字被整洁地封装成一个类,但您需要定义双方交流的语言。对于它们来说,它们只是获取字节数据。您需要某种方式来表明“嘿,我正在发送给你一个文件”,以便另一方知道要期望什么。 - Serguei Fedorov
这就是我所说的端口选择。由于这是我的聊天应用程序,每当选择文件上传时,它将仅发送到特定端口。在另一侧,文件也将仅发送到特定端口,因此它将自动完成正确的操作。 - Dhivya Sadasivam
1
除非你有一个非常好的理由编写自己的协议,否则请尝试使用已经存在的协议(例如HTTP、FTP、XMPP等)。 - Mike Dinescu
我实际上是在一个内部聊天应用程序中使用它。如果我使用HTTP和FTP,这会是一个好的步骤吗? - Dhivya Sadasivam
在您的情况下,由于这是一个聊天应用程序,您可能希望查看XMPP协议:http://xmpp.org/xmpp-protocols/ - Mike Dinescu
显示剩余5条评论
2个回答

2
没有任何检查,这似乎可以工作。您可以添加校验和等,解码b64并保存文件。
public class FileTransfer
{
    public string Name;
    public int Size;
    public string Content;
}

发送:

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

接收:

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

2
文件传输需要两端之间有一个协议。例如,您可以定义一个简单的协议,其中前四个字节指定文件名的大小,接下来的四个字节指定文件的大小。然后发送文件名,再发送内容。这样,您只需要担心线路的两端是否使用大端或小端即可。如果它们相同,那就没问题了。
这就是为什么套接字通常不是进行通信的好选择。有很多现有的传输文件的协议(如HTTP、FTP、AMF等),它们已经为您处理了这些问题。那么,为什么不使用其中之一呢?

你知道哪些类似示例的参考网站吗? - Dhivya Sadasivam
不要忘记,当你想要实现安全性时,像HTTP和FTP这样的协议已经具备了本地支持。 - Ole K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接