C# Socket传输2GB以上大文件时网络环境下Receive超时问题
C# Socket大文件传输超时问题
我尝试使用C#的Socket传输大于2GB的大文件,采用10MB分块的方式。具体实现逻辑为:客户端发送一个数据块后,等待服务器的接收确认,收到确认后再发送下一个数据块,循环直至文件全部发送完成,最后关闭连接。
该方案在本地环境运行正常,但在网络环境下,服务器端的Receive()方法会出现超时异常。
客户端代码
try { DateTime startdate = DateTime.Now; string ori_text = btn_Send_Files.Text; btn_Send_Files.Text = "Do not click already sending..."; btn_Send_Files.Refresh(); IPAddress[] ipAddress = Dns.GetHostAddresses("localhost"); IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5656); Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); clientSock.Connect(ipEnd); label1.Text = label1.Text + "\nConnected to:" + ipEnd.Address.ToString(); label1.Refresh(); string fileName = "CCCCCC.zip"; //It has size greater than 2 GB string filePath = @"C:\Users\CCCCCC\Downloads\"; byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName); label1.Text = label1.Text + "\nSending the file:" + fileName; label1.Refresh(); FileInfo fi = new FileInfo(filePath + fileName); int max = 1024 * 1024 * 10; long start = 0, bytesRead = 0; FileStream fileStream = new FileStream(filePath + fileName, FileMode.Open, FileAccess.Read); max = max - (4 + fileNameByte.Length); byte[] tmpserver = new byte[100]; using (fileStream) { int i = 0; while (start < fi.Length) { i += 1; label1.Text = label1.Text + "\nSending " + i.ToString() + " block of file:" + fileName; label1.Refresh(); fileStream.Seek(start, SeekOrigin.Begin); if (max > (fi.Length - start)) max = Convert.ToInt32(fi.Length - start); byte[] buffer = new byte[max]; byte[] clientData = new byte[4 + fileNameByte.Length + max]; byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); fileNameLen.CopyTo(clientData, 0); fileNameByte.CopyTo(clientData, 4); bytesRead = fileStream.Read(buffer, 0, max); start += max; buffer.CopyTo(clientData, 4 + fileNameByte.Length); clientSock.Send(clientData); Array.Clear(clientData, 0, clientData.Length); Array.Clear(buffer, 0, buffer.Length); Array.Clear(fileNameLen, 0, fileNameLen.Length); Array.Clear(clientData, 0, clientData.Length); clientData = null; buffer = null; fileNameLen = null; GC.Collect(); label1.Text = label1.Text + "\nWaiting for confirmation of " + i.ToString() + " block of file:" + fileName; int serverdata = clientSock.Receive(tmpserver); if (serverdata == 0) { clientSock.Shutdown(SocketShutdown.Both); clientSock.Close(); break; } else { label1.Text = label1.Text + "\nReceived confirmation for " + i.ToString() + " block of file:" + fileName; label1.Refresh(); } } } clientSock.Close(); DateTime enddate = DateTime.Now; TimeSpan diff = startdate - enddate; label1.Text = label1.Text + "\nFile "+ fileName + " has been sent to:"+ ipEnd.Address.ToString(); label1.Text = label1.Text + "\nTime Taken to sent the file(seconds):" + Math.Abs(diff.Seconds).ToString(); label1.Refresh(); btn_Send_Files.Text = ori_text; btn_Send_Files.Refresh(); } catch (Exception ex) { MessageBox.Show("File Sending fail." + ex.ToString()); }
服务器端代码
try { label1.Text = label_text; label1.Refresh(); string ori_btn_text = btn_Start_Server.Text; btn_Start_Server.Text = "Do not click already waiting..."; btn_Start_Server.Refresh(); label1.Text = label1.Text + "\nWaiting for client"; label1.Refresh(); string receivedPath = ConfigurationManager.AppSettings["Location"]; Socket clientSock = sock.Accept(); label1.Text = label1.Text + "\nServer Started and connected to client" + clientSock.LocalEndPoint + "\nWaiting for the file to receive"; label1.Refresh(); int max = 1024*1024*10; string logfile = receivedPath + "\\serverlog.log"; if (File.Exists(logfile)) { File.Delete(logfile); } FileStream fs = File.Create(logfile); byte[] serverdata = new byte[100]; string fileName = ""; int fileNameLen = 0, fileDataLen = 0; int i = 0; BinaryWriter bWrite = null; while (true) { i += 1; byte[] clientData = new byte[max]; int receivedBytesLen = clientSock.Receive(clientData); if (receivedBytesLen <= 0) break; string tmp = "\nStarted:" + i; fs.Write(Encoding.ASCII.GetBytes(tmp), 0, Encoding.ASCII.GetBytes(tmp).Length); if (i == 1) { fileNameLen = BitConverter.ToInt32(clientData, 0); fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen); fileDataLen = BitConverter.ToInt32(clientData, 4); if (File.Exists(receivedPath + fileName)) { File.Delete(receivedPath + fileName); } bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Create)); label1.Text = label1.Text + "\nReceiving File:" + fileName; } label1.Text = label1.Text + "\nReceived " + i.ToString() + " block of file:" + fileName; label1.Refresh(); bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen); Array.Clear(clientData, 0, clientData.Length); clientData = null; GC.Collect(); clientSock.Send(serverdata); label1.Text = label1.Text + "\nSent confirmation for " + i.ToString() + " block of file:" + fileName; label1.Refresh(); } if (bWrite != null) { bWrite.Flush(); bWrite.Dispose(); bWrite.Close(); } fs.Close(); label1.Text = label1.Text + "\nFile has been received:" + fileName; label1.Refresh(); MessageBox.Show("File has been received:" + fileName); btn_Start_Server.Text = ori_btn_text; btn_Start_Server.Refresh(); } catch (Exception ex) { MessageBox.Show("File Receiving fail." + ex.ToString()); }
内容的提问来源于stack exchange,提问作者Bha01
相关产品推荐
相关产品推荐

