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

C# TCP音乐下载客户端无法获取正确文件大小问题排查

TCP服务器-客户端音乐下载文件大小读取错误排查

我用C#开发基础的TCP服务器-客户端音乐下载应用,当前处于最后一步:服务器向客户端传输MP3文件时,先发送文件大小,再以1024字节分块发送文件内容。但客户端始终无法获取正确的文件大小,得到的数值类似193445465,而真实文件大小应为805KB。以下是客户端与服务器的代码,请求排查问题:

客户端代码

private void server1Download_Click(object sender, EventArgs e)
{
    NetworkStream stream = server.GetStream();
    string download_song = searchBar.Text;
    byte[] buffer = Encoding.ASCII.GetBytes("send4thisclient " + download_song);
    stream.Write(buffer, 0, buffer.Length);
    searchBar.Clear();
    stream.Flush();

    Task.Run(() =>
    {
        downloadMusic(download_song);
    });
}


private void downloadMusic(string download_song)
{
    NetworkStream stream = server.GetStream();

    // Read the file size
    byte[] fileSizeBytes = new byte[2 * 2];
    stream.Read(fileSizeBytes, 0, fileSizeBytes.Length);
    int fileSize = BitConverter.ToInt32(fileSizeBytes, 0);


    // Read the file data
    byte[] fileData = new byte[fileSize];
    int bytesReadFileData;
    int totalBytesRead = 0;
    while (totalBytesRead < fileSize && (bytesReadFileData = stream.Read(fileData, totalBytesRead, fileSize - totalBytesRead)) > 0)
    {
        totalBytesRead += bytesReadFileData;
    }

    // Save the downloaded file
    string currentFolder = Environment.CurrentDirectory;
    string filePath = Path.Combine(currentFolder, download_song);
    File.WriteAllBytes(filePath, fileData);
    MessageBox.Show("downloaded");
}

服务器代码

if (message.StartsWith("send4thisclient"))
{
    string[] list = message.Split(" ");
    string sName = list[1];
    string currentDirectory = Directory.GetCurrentDirectory();
    string file = Path.Combine(currentDirectory, sName);

    using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
    {
        // Get the file size
        long fileSize = fileStream.Length;
        byte[] fileSizeBytes = BitConverter.GetBytes(fileSize);

        // Send file size to client
        stream.Write(fileSizeBytes, 0, fileSizeBytes.Length);

        // Send file data to client in chunks
        byte[] buffers = new byte[1024];
        int bytesRead2;

        while ((bytesRead2 = fileStream.Read(buffers, 0, buffers.Length)) > 0)
        {
            stream.Write(buffers, 0, bytesRead2);
        }
    }
}

}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

问题排查与修复

核心问题点

  1. 数据长度不匹配:服务器端用long类型存储文件大小(对应8字节),生成的字节数组也是8字节;但客户端仅分配4字节数组(new byte[2*2]),还用BitConverter.ToInt32解析,导致读取字节不全,解析出错误数值。
  2. 未保证完整读取:NetworkStream.Read()无法确保一次读取到指定长度字节,必须循环读取直到获取足够数据,当前客户端直接调用一次Read可能拿不到完整的文件大小。

修正后的客户端代码

private void downloadMusic(string download_song)
{
    NetworkStream stream = server.GetStream();

    // 读取文件大小:long类型对应8字节
    byte[] fileSizeBytes = new byte[sizeof(long)];
    int bytesRead = 0;
    // 循环读取直到拿到完整的8字节
    while (bytesRead < fileSizeBytes.Length)
    {
        int read = stream.Read(fileSizeBytes, bytesRead, fileSizeBytes.Length - bytesRead);
        if (read == 0)
        {
            MessageBox.Show("连接中断,无法获取文件大小");
            return;
        }
        bytesRead += read;
    }
    // 解析为long类型
    long fileSize = BitConverter.ToInt64(fileSizeBytes, 0);

    // 读取文件内容
    byte[] fileData = new byte[fileSize];
    int totalBytesRead = 0;
    while (totalBytesRead < fileSize && (bytesRead = stream.Read(fileData, totalBytesRead, (int)Math.Min(1024, fileSize - totalBytesRead))) > 0)
    {
        totalBytesRead += bytesRead;
    }

    // 保存文件
    string currentFolder = Environment.CurrentDirectory;
    string filePath = Path.Combine(currentFolder, download_song);
    File.WriteAllBytes(filePath, fileData);
    MessageBox.Show("下载完成");
}

补充说明

  • 服务器端代码无需修改,fileStream.Length返回long类型,生成的字节数组长度正确。
  • 若需跨不同字节序的平台,可通过BitConverter.IsLittleEndian判断后调整字节顺序,同一Windows环境下一般无需额外处理。

内容的提问来源于stack exchange,提问作者aaron swartz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:30:38