在套接字编程c#中发送大文件[重复]

2024-02-18

我想用 c# 中的套接字发送大文件。文件可以传输,但当我想打开它时,我看到它已损坏。有什么问题? 我在客户端代码中将文件分成 2KB 的数组并发送。然后,在服务器代码中,我收到它并将其放入字节数组中并转换为文件。

服务器代码:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace MyServer
{
    class Program
    {
        static void Main(string[] args)
        {
            bool full = false;
            byte[] data = new byte[2049];
            byte[] bsize = new byte[2048];
            List<byte> bytes = new List<byte>();
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            newsock.Bind(ipep);
            newsock.Listen(100);
            Console.WriteLine("Wating For Client ...");
            Socket client = newsock.Accept();
            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
            Console.WriteLine("Connected with {0} at port {1}",clientep.Address,clientep.Port);
            Console.Write("Enter the name of file:  ");
            string Address = Console.ReadLine();
            client.Receive(bsize);
            int size = BitConverter.ToInt32(bsize, 0);
            byte[] bytes2 = new byte[size];
            int k = 0;
            while (true)
            {
                client.Receive(data);
                for(int i = k,j=0; i < k + 2048 && j<2048; i++,j++)
                {
                    if (i == size)
                    {
                        full = true;
                        break;
                    }
                    bytes2[i] = data[j];
                    //bytes.Insert(i,data[j]);
                }
                k += 2048;
                if (full == true)
                    break;
                /*if (bytes.Count >= size)
                    break;*/
            }
            File.WriteAllBytes(@"G:\"+Address,bytes2 /*bytes.ToArray()*/);
            Console.WriteLine("Disconnected from Client {0}",clientep.Address);
            client.Close();
            newsock.Close();
            Console.ReadKey();
        }
    }
}

客户端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace MyClient
{
    class Program
    {
        static void Main(string[] args)
        {
            int reza = 0;
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.0.2"), 9050);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                server.Connect(ipep);
            }
            catch (SocketException e)
            {
                Console.WriteLine("Unable to connect to Server");
                Console.WriteLine(e.ToString());
                Console.ReadKey();
                return;
            }
            Console.Write("Enter Address Of File:");
            string Address = Console.ReadLine();
            FileStream File = new FileStream(Address, FileMode.Open, FileAccess.Read);
            byte[] bytes = System.IO.File.ReadAllBytes(@Address);
            File.Close();
            byte[] data = new byte[2048];
            byte[] Size = BitConverter.GetBytes(bytes.Length);
            server.Send(Size, Size.Length, SocketFlags.None);
            for (int i = 0; i <= bytes.Length; i +=2048)
            {
                int k = i + 2048;
                for(int j=i,d=0 ;j< k && j<bytes.Length; j++,d++)
                {
                    data[d] = bytes[j];
                    reza++;
                }
                if (reza == 2048)
                {
                    server.Send(data, data.Length, SocketFlags.None);
                    Console.Write("*");
                    reza = 0;
                }
                else
                {
                    server.Send(data, reza, SocketFlags.None);
                    Console.WriteLine("*");
                }
            }
            Console.WriteLine("Disconnecting from server ...");
            server.Shutdown(SocketShutdown.Both);
            server.Close();
            Console.ReadKey();
        }
    }
}

问题是你忽略了返回值Receive()。无法保证您的缓冲区将被完全填满。

返回值告诉您套接字实际从网络读取了多少数据。调整您的接收代码,以便将其考虑在内。发送也是如此。如果内部套接字缓冲区已满,它将报告发送的字节数少于您请求发送的字节数。

除此之外,我建议您开始为变量指定有意义的名称。您的代码的可读性不太好。

这是一个更好的接收例程:

var fileBuffer = new byte[size];
var receiveBuffer = new byte[2048];
var bytesLeftToReceive = size;
var fileOffset = 0;

while (bytesLeftToReceive > 0)
{
    //receive
    var bytesRead = client.Receive(receiveBuffer);
    if (bytesRead == 0) 
        throw new InvalidOperationException("Remote endpoint disconnected");

    //if the socket is used for other things after the file transfer
    //we need to make sure that we do not copy that data
    //to the file
    int bytesToCopy = Math.Min(bytesRead, bytesLeftToReceive);

    // copy data from our socket buffer to the file buffer.
    Buffer.BlockCopy(receiveBuffer, 0, bytesLeftToReceive, fileBuffer, fileOffset);

    //move forward in the file buffer
    fileOffset += bytesToCopy;

    //update our tracker.
    bytesLeftToReceive -= bytesToCopy;
}

但是,既然要传输大文件,那么直接将其写入文件流不是更好吗?

var stream = File.Create(@"C:\path\to\file.dat");
var receiveBuffer = new byte[2048];
var bytesLeftToReceive = size;

while (bytesLeftToReceive > 0)
{
    //receive
    var bytesRead = client.Receive(receiveBuffer);
    if (bytesRead == 0) 
        throw new InvalidOperationException("Remote endpoint disconnected");

    //if the socket is used for other things after the file transfer
    //we need to make sure that we do not copy that data
    //to the file
    int bytesToCopy = Math.Min(bytesRead, bytesLeftToReceive);

    // write to file
    stream.Write(receiveBuffer, 0, bytesToCopy);

    //update our tracker.
    bytesLeftToReceive -= bytesToCopy;
}

在发送端我会做这样的事情:

// read directly from the file to reduce memory usage.
var fileName = @"....";
using (var file = File.OpenRead(fileName))
{
    var sendBuffer = new byte[2048];
    var fileSize = BitConverter.GetBytes((int)file.Length);
    server.Send(fileSize, fileSize.Length, SocketFlags.None);

    var bytesLeftToTransmit = fileSize;
    while (bytesLeftToTransmit > 0)
    {
        var dataToSend = file.Read(sendBuffer, 0, sendBuffer.Length);
        bytesLeftToTransmit -= dataToSend;

        //loop until the socket have sent everything in the buffer.
        var offset=0;
        while (dataToSend > 0)
        {
            var bytesSent = socket.Send(sendBuffer, offset, dataToSend);
            dataToSend -= bytesSent;
            offset += bytesSent;
        }
    }
}

最后你有一个套接字发送文件 https://msdn.microsoft.com/en-us/library/sx0a40c2(v=vs.110).aspx已针对发送文件进行了优化。您可以随时为打开的套接字调用它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在套接字编程c#中发送大文件[重复] 的相关文章

  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • ' | Home'))' aria-label='使用规范进行测试,railstutorial 第 3 章中的水豚不起作用 (have_selector('title', :text => ' | Home'))'> 使用规范进行测试,railstutorial 第 3 章中的水豚不起作用 (have_selector('title', :text => ' | Home'))

    我正在处理 ruby railstutorial org ruby on rails tutorial book 我使用 Rails 3 2 7 spork rspec capybara launchy 和一些 Guards 我在第三章的测
  • tensorflow gpu仅在CPU上运行

    我在 Windows 10 上安装了 Anaconda Navigator 和所有必需的 Nvidia Cuda 软件包 创建了一个名为 tensorflow gpu env 的新环境 更新了 PATH 信息等 当我运行模型时 使用tens
  • Google 是否/将会在 Firebase 崩溃报告中支持 NDK C++ 崩溃?

    我试图从文档中找出Google是否支持新发布的NDK C 崩溃Firebase 崩溃报告 https firebase google com docs crash 到目前为止 我只看到了 Java 崩溃支持 有谁知道 Google 是否计划
  • 列表的编辑器模板

    我希望为我的 ASP NET MVC3 站点中的一些基本模型创建一个通用编辑器 现在它们可以包含字符串 布尔值 枚举和列表集合 我想要做的是扩展默认编辑器模板以识别列表并显示一个自定义编辑器 该编辑器可以向该列表添加和删除字符串 其他所有的
  • 没有某些字段的深度克隆

    让我有下一个 javascript 对象 现在我想克隆它但没有一些字段 例如我想要没有字段的克隆对象 lastName and cars age Input firstName Fred lastName McDonald cars typ
  • Xcode 9 GM 种子模拟器屏幕工件

    我遇到了模拟器屏幕问题 安装了最后一个测试版后 当我构建任何项目时 它会随机发生 通常在我点击播放时发生 3 4 次 必须退出模拟器应用程序 然后重新启动它 有人有同样的问题吗 Screenshot Metal 似乎是新模拟器的默认渲染器
  • 骨干监听模型中对象的变化

    我可以监听模型中某个对象的任何变化吗 我知道如何监听模型更改 但我只需要监听模型和视图中的对象 var view Backbone View extend func initialize function this listenTo thi
  • redis数据库中HSET和HMSET方法有什么区别

    在我的应用程序中 我使用 redis 数据库 我已经阅读了他们的文档 但我找不到 HSET 和 HMSET 之间的区别 HSET 过去只能设置一个键值对 如果您需要一次设置多个 则必须使用 HMSET M 表示多个 几年前这一情况发生了变化
  • 如何在 VBScript 中将二进制数据写入磁盘?

    我有一个二进制字符串需要写入文件 我有一种感觉 这should是一个简单的程序 但话又说回来 VBScript 这FileSystemObject没有任何帮助 因为它会破坏数据 这Stream该物体看起来很有前途 它的adBinaryMod
  • 与 django 查询集注释中先前对象的差异

    假设我有以下模型 class TestModel models Model some integer models IntegerField 我有这个模型的 3 个实例 TestModel objects create some integ
  • 如何根据光标悬停移动背景?

    当光标悬停在滑块上时 背景也会随着光标悬停而移动 下面的链接 这是使用此效果的网站链接 泰勒马鲁克 http www telemaruk com 这种效应叫什么 以及如何达到这个效果 任何有用的链接请 它是某种 jquery 插件或简单的
  • 在 Kubernetes 上创建 mysql 容器时如何初始化?

    我想在容器的MySQL上设置初始数据 在 docker compose yml 中 此类代码可以在运行容器时创建初始数据 volumes db var lib mysql docker mysql conf d etc mysql conf
  • 列出可用的网络打印机(也未安装)[重复]

    这个问题在这里已经有答案了 这意味着我可以枚举所有打印机 网络和本地 但前提是它们安装在我的电脑上 但是 我希望能够列出那些未安装的并且可以通过使用 Windows 内置 添加打印机 对话框查看的打印机 这是否可能 因为我在浏览各种论坛 板
  • Spring Data JPA - 多个 EnableJpaRepositories

    我的应用程序有多个数据源 因此我基于此创建了两个数据源配置类URL https github com spring projects spring data examples tree master jpa multiple datasou
  • ZipFile 关闭后 ZipEntry 是否仍然存在?

    目前 我的库中存在看似合理的资源泄漏 因为我将 ZipFile 保持打开状态 因此某个 ZipEntry 返回的 InputStream 未关闭 但是 关闭返回的 InputStream 并不会关闭 ZipFile 的其余部分 因此我坚持将
  • 判断两个Git分支是否有分歧

    我想确定两个 Git 分支是否有分歧 或者其中一个分支是否可以简单地快速转发到另一个分支 换句话说 我想检查其中一个分支的当前 HEAD 是否已在某个时刻合并到另一个分支中 或者它是否包含不在另一个分支中的提交 有没有办法在不实际合并两个分
  • 带 VideoView 的无缝视频循环

    我有以下代码将视频作为原始资源 启动视频并循环播放 但我需要视频在剪辑结束时无缝循环 并再次启动剪辑 之间的转换会导致闪烁一瞬间 我的应用程序确实无法做到这一点 public class Example extends Activity V
  • 获取所有大于某个值的 stl 向量元素

    我想知道如何找到具有验证特定条件的值的 stl 向量元素列表 例如 如果我有一个 int 值向量 vector
  • 从Linux调用Windows批处理文件

    我有一个仅在 Windows 上运行的应用程序和一个启动它的批处理文件 我想从 Linux 调用这个批处理文件 这意味着 Linux 批处理之类的东西将使用参数启动 Windows 批处理 然后依次运行我的应用程序 我可以这样做吗 如何 你
  • 在套接字编程c#中发送大文件[重复]

    这个问题在这里已经有答案了 我想用 c 中的套接字发送大文件 文件可以传输 但当我想打开它时 我看到它已损坏 有什么问题 我在客户端代码中将文件分成 2KB 的数组并发送 然后 在服务器代码中 我收到它并将其放入字节数组中并转换为文件 服务