C# 通过tcp连接发送大文件
我需要通过互联网向计算机发送一些大文件。因此,我打开了我计划在路由器上使用的端口,并转发相应的ip地址。无论如何,让我向你们展示我为了实现这一目标而一直在学习的课程。这些类在处理小文件时效果很好,但有时在处理大文件时会失败 以下是服务器的代码:(它是一个控制台应用程序) 在执行该代码之前,必须先运行服务器C# 通过tcp连接发送大文件,c#,networking,tcp,C#,Networking,Tcp,我需要通过互联网向计算机发送一些大文件。因此,我打开了我计划在路由器上使用的端口,并转发相应的ip地址。无论如何,让我向你们展示我为了实现这一目标而一直在学习的课程。这些类在处理小文件时效果很好,但有时在处理大文件时会失败 以下是服务器的代码:(它是一个控制台应用程序) 在执行该代码之前,必须先运行服务器 我不知道为什么使用套接字通过internet发送文件如此复杂。我不知道WCF,这就是为什么我在创建这些类时浪费了很多时间。也许已经有一些内置的类可以让我通过互联网将文件发送到另一台计算机。我只
我不知道为什么使用套接字通过internet发送文件如此复杂。我不知道WCF,这就是为什么我在创建这些类时浪费了很多时间。也许已经有一些内置的类可以让我通过互联网将文件发送到另一台计算机。我只知道网络的基本知识,如果我能用一个简单的类来完成,那就太好了。我不明白为什么我的课不一直上课?如果我增加缓冲区大小,我的类会更有效率吗?在发送更多字节之前,我是否需要等待或暂停程序?如果有人能告诉我这门课有什么问题就好了。它们在处理小文件时效果很好,但在处理大文件时有时不起作用…通过套接字发送文件/目录并不简单。我建议使用一些文件传输库(通过套接字,或者更高级别的协议,例如rsync、ftp、http等),而不是尝试从头开始编写代码
浏览完代码后-尝试发送一个包含统一内容的大文件(填充“0”或其他内容)。如果它会通过-您的xml东西不起作用 我可以马上看到一些问题。可能导致您的程序只在某些时间工作的一个原因是,通过TCP发送不会保证每次
send
都会在另一端产生大小相同的receive
您的协议似乎假定它会这样做,因为您正在等待
的读取正好是11个字节,而它可以在多个单独的读取中接收。例如:“[文件数据…]”。如果发生这种情况,代码将无法正确完成
还值得注意的是,ASCII编码是7位的,因此二进制文件(如MP4)将被错误地接收(即使您修复了上述问题)。如果是二进制数据,则不应尝试将其转换为字符串,而应直接从字节[]
将其写入文件
如果您希望继续沿着这条路线前进(而不是使用另一个答案中提到的许多现有文件传输系统),那么您可能还希望更改协议,以便不使用
…
分隔文件,而是首先发送文件的长度,这将允许您发送可能包含这些特殊标记之一的文件。基本上您所做的是正确的。我建议改进的要点是将MaxChunkSize
设置为更大的值,高达65000。这将使套接字代码能够处理任何碎片,这将比您自己进行的任何拆分更加有效
另外,您知道发送一个大文件需要一些时间。在100 Mbit LAN上,带宽(理论上)为每秒12.5 MByte。因此,发送一个700兆字节的文件仍然需要56秒。当然,实际吞吐量取决于网络、计算机和网络硬件中的许多因素,因此预计速度会较慢
最后,(或任何其他嗅探器程序)是网络程序员工具箱中最基本和最宝贵的工具。在服务器和客户机上都使用它来查看TCP数据包是如何传输的,看看是否可以确定传输速度慢的原因。以下是我发送大文件的代码。 一些提示:
- 检查缓冲区大小。如果它太大,它就会失败
- 套接字标志。部分标志效果最好
- 由于传输时间的原因,需要套接字超时
string IPAddress = "";
int Port = 500;
string Filename = @"C:\Users\Ben\Desktop\TT.zip";
int bufferSize = 1024;
byte[] buffer = null;
byte[] header = null;
FileStream fs = new FileStream(Filename, FileMode.Open);
bool read = true;
int bufferCount = Convert.ToInt32(Math.Ceiling((double)fs.Length / (double)bufferSize));
TcpClient tcpClient = new TcpClient(IPAddress, Port);
tcpClient.SendTimeout = 600000;
tcpClient.ReceiveTimeout = 600000;
string headerStr = "Content-length:" + fs.Length.ToString() + "\r\nFilename:" + @"C:\Users\Administrator\Desktop\" + "test.zip\r\n";
header = new byte[bufferSize];
Array.Copy(Encoding.ASCII.GetBytes(headerStr), header, Encoding.ASCII.GetBytes(headerStr).Length);
tcpClient.Client.Send(header);
for (int i = 0; i < bufferCount; i++)
{
buffer = new byte[bufferSize];
int size = fs.Read(buffer, 0, bufferSize);
tcpClient.Client.Send(buffer,size,SocketFlags.Partial);
}
tcpClient.Client.Close();
fs.Close();
字符串IPAddress=”“;
int端口=500;
字符串文件名=@“C:\Users\Ben\Desktop\TT.zip”;
int bufferSize=1024;
字节[]缓冲区=空;
字节[]头=空;
FileStream fs=newfilestream(文件名,FileMode.Open);
bool read=true;
int bufferCount=Convert.ToInt32(数学上限((双)fs.Length/(双)bufferSize));
TcpClient TcpClient=新的TcpClient(IP地址,端口);
tcpClient.SendTimeout=600000;
tcpClient.ReceiveTimeout=600000;
字符串headerStr=“内容长度:”+fs.length.ToString()+”\r\n文件名:“++”C:\Users\Administrator\Desktop\“+”test.zip\r\n”;
header=新字节[bufferSize];
Copy(Encoding.ASCII.GetBytes(headerStr),header,Encoding.ASCII.GetBytes(headerStr).Length);
tcpClient.Client.Send(头);
for(int i=0;i
服务器:
int Port = 500;
TcpListener listener = new TcpListener(IPAddress.Any, Port);
listener.Start();
Socket socket = listener.AcceptSocket();
int bufferSize = 1024;
byte[] buffer = null;
byte[] header = null;
string headerStr = "";
string filename = "";
int filesize = 0;
header = new byte[bufferSize];
socket.Receive(header);
headerStr = Encoding.ASCII.GetString(header);
string[] splitted = headerStr.Split(new string[] { "\r\n" }, StringSplitOptions.None);
Dictionary<string, string> headers = new Dictionary<string, string>();
foreach (string s in splitted)
{
if (s.Contains(":"))
{
headers.Add(s.Substring(0,s.IndexOf(":")), s.Substring(s.IndexOf(":") + 1));
}
}
//Get filesize from header
filesize = Convert.ToInt32(headers["Content-length"]);
//Get filename from header
filename = headers["Filename"];
int bufferCount = Convert.ToInt32(Math.Ceiling((double)filesize / (double)bufferSize));
FileStream fs = new FileStream(filename, FileMode.OpenOrCreate);
while(filesize > 0)
{
buffer = new byte[bufferSize];
int size = socket.Receive(buffer,SocketFlags.Partial);
fs.Write(buffer,0,size);
filesize -= size;
}
fs.Close();
int端口=500;
TcpListener listener=新的TcpListener(IPAddress.Any,Port);
listener.Start();
Socket=listener.AcceptSocket();
int bufferSize=1024;
字节[]缓冲区=空;
字节[]头=空;
字符串头STR=“”;
字符串filename=“”;
int filesize=0;
header=新字节[bufferSize];
套接字接收(报头);
headerStr=Encoding.ASCII.GetString(header);
string[]splitted=headerStr.Split(新字符串[]{“\r\n”},StringSplitOptions.None);
字典头=新字典();
foreach(拆分中的字符串s)
Client c = new Client("192.168.0.196");
c.sendFile(@"A:\Users\Tono\Desktop\a.mp4");
string IPAddress = "";
int Port = 500;
string Filename = @"C:\Users\Ben\Desktop\TT.zip";
int bufferSize = 1024;
byte[] buffer = null;
byte[] header = null;
FileStream fs = new FileStream(Filename, FileMode.Open);
bool read = true;
int bufferCount = Convert.ToInt32(Math.Ceiling((double)fs.Length / (double)bufferSize));
TcpClient tcpClient = new TcpClient(IPAddress, Port);
tcpClient.SendTimeout = 600000;
tcpClient.ReceiveTimeout = 600000;
string headerStr = "Content-length:" + fs.Length.ToString() + "\r\nFilename:" + @"C:\Users\Administrator\Desktop\" + "test.zip\r\n";
header = new byte[bufferSize];
Array.Copy(Encoding.ASCII.GetBytes(headerStr), header, Encoding.ASCII.GetBytes(headerStr).Length);
tcpClient.Client.Send(header);
for (int i = 0; i < bufferCount; i++)
{
buffer = new byte[bufferSize];
int size = fs.Read(buffer, 0, bufferSize);
tcpClient.Client.Send(buffer,size,SocketFlags.Partial);
}
tcpClient.Client.Close();
fs.Close();
int Port = 500;
TcpListener listener = new TcpListener(IPAddress.Any, Port);
listener.Start();
Socket socket = listener.AcceptSocket();
int bufferSize = 1024;
byte[] buffer = null;
byte[] header = null;
string headerStr = "";
string filename = "";
int filesize = 0;
header = new byte[bufferSize];
socket.Receive(header);
headerStr = Encoding.ASCII.GetString(header);
string[] splitted = headerStr.Split(new string[] { "\r\n" }, StringSplitOptions.None);
Dictionary<string, string> headers = new Dictionary<string, string>();
foreach (string s in splitted)
{
if (s.Contains(":"))
{
headers.Add(s.Substring(0,s.IndexOf(":")), s.Substring(s.IndexOf(":") + 1));
}
}
//Get filesize from header
filesize = Convert.ToInt32(headers["Content-length"]);
//Get filename from header
filename = headers["Filename"];
int bufferCount = Convert.ToInt32(Math.Ceiling((double)filesize / (double)bufferSize));
FileStream fs = new FileStream(filename, FileMode.OpenOrCreate);
while(filesize > 0)
{
buffer = new byte[bufferSize];
int size = socket.Receive(buffer,SocketFlags.Partial);
fs.Write(buffer,0,size);
filesize -= size;
}
fs.Close();