You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:39:18