草庐IT

c# - TCP Socket SendAsync 操作是否可以在不传输 BufferList 中的所有字节的情况下完成?

coder 2023-07-13 原文

在 Mono 3.12 上,我使用 Socket.SendAsync(SocketAsyncEventArgs)使用 TCP Stream Socket 来实现基于请求的流协议(protocol)。我正在使用 SocketAsyncEventArgs.BufferList设置多个数据缓冲区。

Socket 的文档中和 SocketAsyncEventArgs , 我找不到任何关于 SocketAsyncEventArgs.Completed 的提及当使用 BufferList 时,可以在不发送所有字节的情况下引发,留下我们必须根据 SocketAsyncEventArgs.BytesTransferred 进行验证的印象.

另一方面,Socket.BeginSend做出这样的保证

When your application calls BeginSend, the system will use a separate thread to execute the specified callback method, and will block on EndSend until the Socket sends the number of bytes requested or throws an exception.

当使用 SendAsyncSocketAsyncEventArgs.BufferList 时,规范对传输的字节数有何保证?

假设事件以 SocketError.Success 完成.

最佳答案

在将 SendAsync 与 SocketAsyncEventArgs.BufferList 一起使用时,规范对传输的字节数有何保证?

首先,可以在出现错误时引发事件,在这种情况下,您可以假设并非所有字节都已传输。为此,您需要测试 SocketAsyncEventArgs.SocketError 的 SocketError.Success。此外,如果您提到“规范”,我假设您指的是 (Microsoft) Windows Sockets 文档(因为您链接到此以获取 SendAsync 和其他描述)。

为了在成功调用 Completed 事件时也弄清楚文档对传输字节数的说明或暗示,我们必须执行几个步骤。第一步是查看 SendAsync 是否使用重叠 I/O。 Overlapped Input / Output 中回答了这个问题文档。此机制的实现对于底层传输提供程序是强制性的,因此它是唯一保证可用于 Windows 套接字的重叠 I/O 机制。因此,SendAsync 保证使用具有 WSA_FLAG_OVERLAPPED 属性的套接字。

请注意检查 SendAsync reference implementation显示 SendAsync 确实使用了具有重叠 I/O 的 WSASend,但这只是一个观察。

第二步是确定重叠的 I/O 告诉我们哪些有关已完成事件的信号与传输的字节数有关。这种情况在几个地方都有描述,例如在这个 Overlapped I/I and Event Objects页面:“当发送缓冲区已被消耗时将提供指示”。 [WSASend] 函数的备注部分给出了更多细节:“当缓冲区已被传输消耗时,将出现完成指示,调用例程的完成或事件对象的设置” .

这仍然为准确解释这句话留下了一些空间。基本上它表示数据已被套接字范围外的底层传输机制接受和确认。这并不一定意味着它已经到达远程端点协议(protocol)层,这取决于通信协议(protocol)。对于 TCP 流套接字,我会推断它表明数据已到达远程端点。

这里的结论是文档保证(对于非错误情况)仅在所有字节都已传输时引发 SendAsync 完成事件。

关于c# - TCP Socket SendAsync 操作是否可以在不传输 BufferList 中的所有字节的情况下完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41470548/

有关c# - TCP Socket SendAsync 操作是否可以在不传输 BufferList 中的所有字节的情况下完成?的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  3. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  4. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  6. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  7. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  8. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  10. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

随机推荐