C# Begin/EndReceive - 如何读取大数据?

2024-04-15

当以 1024 字节为单位读取数据时,如何继续从接收大于 1024 字节的消息的套接字读取数据,直到没有剩余数据为止?我是否应该仅使用 BeginReceive 来读取数据包的长度前缀,然后在检索到该前缀后,使用 Receive() (在异步线程中)来读取数据包的其余部分?或者还有别的办法吗?

edit:

我认为 Jon Skeet 的链接有解决方案,但该代码有一些障碍。我使用的代码是:

public class StateObject
{
    public Socket workSocket = null;
    public const int BUFFER_SIZE = 1024;
    public byte[] buffer = new byte[BUFFER_SIZE];
    public StringBuilder sb = new StringBuilder();
}

public static void Read_Callback(IAsyncResult ar)
{
    StateObject so = (StateObject) ar.AsyncState;
    Socket s = so.workSocket;
    
    int read = s.EndReceive(ar);
    
    if (read > 0) 
    {
        so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));

        if (read == StateObject.BUFFER_SIZE)
        {
            s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, 
                    new AyncCallback(Async_Send_Receive.Read_Callback), so);
            return;
        }
    }
    
    if (so.sb.Length > 0)
    {
        //All of the data has been read, so displays it to the console
        string strContent;
        strContent = so.sb.ToString();
        Console.WriteLine(String.Format("Read {0} byte from socket" + 
        "data = {1} ", strContent.Length, strContent));
    }
    s.Close();
}

现在,这种更正后的方法在大多数情况下都可以正常工作,但在以下情况下会失败数据包的大小是缓冲区的倍数。这样做的原因是,如果缓冲区在读取时被填满,则假定有更多数据;但和以前一样的问题发生了。例如,2 字节缓冲区在 4 字节数据包上被填充两次,并假设有更多数据。然后它会阻塞,因为没有任何内容可供读取。问题是接收函数不知道数据包何时结束。


这让我想到了两种可能的解决方案:我可以有一个数据包结束定界符,或者我可以读取数据包标头以找到长度,然后准确接收该数量(正如我最初建议的那样)。

但这些都存在问题。我不喜欢使用分隔符的想法,因为用户可以以某种方式将其放入应用程序输入字符串中的数据包中,然后将其搞砸。对我来说这也显得有点草率。

长度标头听起来不错,但我计划使用协议缓冲区 - 我不知道数据的格式。有长度标头吗?它有多少字节?这是我自己实现的吗? ETC..

我应该怎么办?


不接电话BeginReceive再次从回调处理程序中,直到EndReceive返回 0。基本上,假设您希望充分利用异步 IO 的优势,您应该继续异步接收。

如果您查看 MSDN 页面Socket.BeginReceive http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx你会看到这样的一个例子。 (诚​​然,这并不像想象的那么容易理解。)

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

C# Begin/EndReceive - 如何读取大数据? 的相关文章

  • 通过另一个列表更新列表(linq)

    我有类 Data 的对象列表 如下所示 class Data int code string name DateTime date update 我还有另一个课程列表 例如 class RefCodes int old code int n
  • 当其源是 https uri 时如何使 wpf MediaElement 播放

    在 wpf 独立应用程序 exe 中 我在主窗口中包含了 MediaElement
  • Ruby on Rails:如何使用 TCP 套接字连接 GPS 设备

    ruby 2 3 0p0 2015 12 25 修订版 53290 x86 64 linux 轨道 4 2 4 我正在使用 cloud9 IDE 和 webrick 服务器 我的项目是实时跟踪GPS 我想使用TCP连接与GPS跟踪设备进行通
  • OpenGL缓冲区更新[重复]

    这个问题在这里已经有答案了 目前我正在编写一个模拟水的程序 以下是我所做的步骤 创建水面 平面 创建VAO 创建顶点缓冲区对象 在其中存储法线和顶点 将指针绑定到此 VBO 创建索引缓冲区对象 然后我使用 glDrawElements 渲染
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • 无法获取本地或参数的值,因为它在此指令指针处不可用,可能是因为它已被优化掉

    Visual Studio 2010 会删除 没有其他词 不安全块中函数参数之一中的数据 什么可能导致此错误 调试器显示以下消息 Cannot obtain value of local or argument as it is not a
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 编写具有多种类型的泛型扩展方法时的类型推断问题

    我正在为 IEnumerable 编写一个通用扩展方法 用于将对象列表映射到另一个映射对象列表 这就是我希望该方法的工作方式 IList
  • 从点云检测平面集

    我有一组点云 我想测试3D房间中是否有角落 所以我想讨论一下我的方法 以及在速度方面是否有更好的方法 因为我想在手机上测试它 我将尝试使用霍夫变换来检测线 然后我将尝试查看是否有三条线相交 并且它们也形成了两个相交的平面 如果点云数据来自深
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 如何对STL向量进行排序?

    我想排序一个vector vector
  • 在 mvc4 中创建通用 mvc 视图

    我以前也提过类似的问题 没有得到答案 如何创建一个通用的 mvc4 视图 该视图可以显示传递给它的模型列表或单个模型 模型可以是个人 组织或团体 无论传递给它的是什么 如果您正在寻找类似的东西 model MyViewModel
  • 不使用放置 new 返回的指针时的 C++ 严格别名

    这可能会导致未定义的行为吗 uint8 t storage 4 We assume storage is properly aligned here int32 t intPtr new void storage int32 t 4 I k
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类

随机推荐

  • 无法在 android studio 中加载包装器属性

    请帮助我 当我在 android studio 中创建一个新项目时出现错误 无法从 C Users baren AndroidStudioProjects ToyaGarage gradle wrapper gradle wrapper p
  • 无法在 Android Studio 中的项目结构上添加模块

    结构项目窗口不显示所有选项 我无法添加库或模块 Check the image And this is how it should look with all the options 我尝试修复重新安装 android studio 但没有
  • 使用 CGRectZero 在 UIView 类或子类上调用 initWithFrame 意味着什么?

    我见过调用的代码initWithFrame of a UIView子类 例如UILabel with CGRectZero一切似乎都进展顺利 实例化一个是什么意思UIView具有 2D 点的子类 这似乎是CGRectZero is 它只是意
  • Dplyr,非标准评估和 Walrus 运算符和 curly-curly

    一个真正的问题 每当我需要编写 dplyr 函数时 我都会随机应变 我知道卷曲运算符可以大大简化任务 https www tidyverse org blog 2019 06 rlang 0 4 0 https www tidyverse
  • 如何使用 javascript 客户端设置 Python 服务器端

    因此 已经设置了一个在我必须构建的控制台上运行的 Python 程序 我将使用 Javascript 为应用程序构建一个 Web GUI 界面 我会怎样 A 继续处理该 Python 程序的输入 输出 而无需触及原始代码 b 通过 Java
  • 为什么我收到“Proto 类已在文件中定义”?

    第一个原型文件 main proto 位于offline目录 option java package com xxx proto option java outer classname Service1 option java multip
  • Android在布局中绘制分隔线/分隔线?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我想在布局的中间画一条线 并将其用作其他项目 如 TextView 的分隔符 有没有一个
  • OpenCV - 将 PNG 的透明部分变成白色

    我是 OpenCV 的新手 所以如果我的问题对你来说很愚蠢 请耐心等待 I have a set of images that all have a transparent border on the left and right like
  • 无法解决Python中的TypeError消息

    我一直在四处寻找 以检查为什么在第 7 行有一个 TypeError 它表示我的参数在字符串格式化期间没有转换 但可以使用 这里有没有人能够帮助我并让我知道我的代码到底出了什么问题 以便我能够纠正自己 以下是我的代码的参考 import s
  • 为什么 GETDATE() 不能用作过程参数的默认值或 EXECUTE 语句中的值?

    考虑以下存储过程 CREATE OR ALTER PROCEDURE MySchema MyProcedure myDateTimeParam DATETIME GETDATE AS BEGIN Do something spectacul
  • YouTubePlayerAPI 分发时间表?

    当我发现这个时我非常兴奋谷歌IO视频 http youtu be 3WFsx u q3Y最近 与当前选项 意图 iframe 嵌入 相比 轻松向应用程序添加 YouTube 功能非常有吸引力 令我惊讶的是 尽管距离发布已有几个月了 但除了这
  • 数据融合 - http post 插件问题

    我正在尝试使用 DataFusion 进行 http 调用 来源 GCS csv 文件 接收器 HTTP POST API 期望该文件作为 HTTP 请求的一部分 执行此操作后 我在 API 日志中收到以下错误 所需的请求部分 文件 不存在
  • 在锚链接中添加工具提示[重复]

    这个问题已经存在了 我想在文本中添加工具提示 例如 如果我有这样的代码 a href http google com title Google a 鼠标悬停时 我想显示该工具提示 使用title这是一个好方法 但是我怎样才能让它看起来更好呢
  • Excel 2010:通过外部连接替换表格而不影响其他工作表

    我有一本包含大量数据的大工作簿 在一张纸上我有一张桌子 该表用于其他工作表中使用的许多数据透视表 这些数据透视表也用于其他工作表中 该表的数据是定期手动复制的 我现在有一个外部连接可以自动导入数据 但我想避免影响其他工作表 如何使用外部连接
  • 在 ruby​​ on Rails 4 中上传图像或文件

    在这里 我想要一个关于在不使用任何 gemfile 例如 peperclip carrierwave 等 的情况下上传文件或图像的清晰概念 之前 我做了一些工作 我可以在 assets images 文件夹中上传图像 但是当我在显示页面中调
  • 转置逗号分隔字段

    我有一个如下所示的数据集 并且正在使用 SAS Enterprise Guide 6 3 data have input id state cards 134 NC NY SC 145 AL NC NY SC run 我有另一个数据集 其中
  • 像 MySQL 一样从 Firebase 检索计数数据

    当尝试从 MySQL 数据库中提取数据时 我可以执行以下操作 SELECT FROM users ORDER BY id WHERE vehicle car 例如 这应该让我获得所有驾驶汽车的用户 而不是显示驾驶摩托车的用户 Firebas
  • 表单:避免将非提交字段设置为 null

    我有一个简单的模型 源简化 class Collection public page public limit 以及表单类型 class CollectionType extends AbstractType public function
  • 调用类指针上的方法[重复]

    这个问题在这里已经有答案了 并不是说我有问题 而是我发现以下事实很奇怪 Class Shape class Shape protected int width height public Shape int a 0 int b 0 widt
  • C# Begin/EndReceive - 如何读取大数据?

    当以 1024 字节为单位读取数据时 如何继续从接收大于 1024 字节的消息的套接字读取数据 直到没有剩余数据为止 我是否应该仅使用 BeginReceive 来读取数据包的长度前缀 然后在检索到该前缀后 使用 Receive 在异步线程