wpf 使用套接字传输文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19730098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File transfer using Sockets
提问by Dhivya Sadasivam
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.
我需要根据他的 IP 地址和特定端口将所有类型的文件传输到特定用户。它在另一个端口传输一些聊天消息。
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();
}
回答by David Arno
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?
这就是为什么套接字通常不是通信的好选择。有许多现有的文件传输协议(HTTP、FTP、AMF 等),它们已经为您处理了这些事情。那么为什么不使用其中之一呢?
回答by Ceelie
Without any checking, this seems to work. You can add checksums etc., decode the b64 save the file.
没有任何检查,这似乎有效。您可以添加校验和等,解码 b64 保存文件。
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();

