我不太明白当 TcpListener 和 TcpClient 通信时,一些功能是如何共享的。
假设运行了以下代码(现在忽略同步):
服务器:
Dim server As New TcpListener(localAddr, port)
server.Start()
Dim client As TcpClient = server.AcceptTcpClient()
客户:
Dim client As New TcpClient
client.Connect(hostAddr, port)
连接成功。现在有两个 TcpClient 实例——一个在服务器端,一个在客户端。但是,它们通过 TcpClient.GetStream() 共享相同的网络流。
我有点困惑 — 当 server.AcceptTcpClient() 被调用时,客户端是否将自身及其所有属性传递给服务器?
在这之后对任一 TcpClient 实例的任何更改如何?当连接关闭时,我在两侧调用它:
client.GetStream.Close()
client.Close()
但是我在执行此代码的客户端上遇到了 TcpClient.GetStream.Close() 异常,因为它告诉我客户端已经关闭(当上面的代码未执行时会发生这种情况双方完全同步)。
.SendBufferSize 和 .ReceiveBufferSize 属性呢?我是否需要在连接的两端进行设置?
希望有人可以通过解释 TcpClient/Listener 类在通信过程中究竟如何工作来消除我的困惑 — 到目前为止,我还没有找到解释到底发生了什么的文档。
最佳答案
TCP 协议(protocol)不知道什么是TcpClient。这是一个.NET 概念。 TCP 根本不引用 .NET 概念。因此,不会通过网络发送任何对象。
唯一发送的是您明确写入的字节。
每一面都有自己独立的对象。双方都使用自己的 TcpClient 对象,它充当 TCP 连接的句柄。
client.GetStream.Close()
client.Close()
这不是正确的关机顺序。第一行相对于第二行是多余的,而且不完整。永远不要调用 Close。最好的方法是将客户端包装在 using 中。第二种最佳方法是在客户端调用 Dispose。 BCL 中的 Close 方法是历史性事件,应该忽略。在我曾经看过的所有情况下,它们所做的事情与 Dispose 所做的相同。
不要触摸缓冲区大小。它们控制内核使用多少内存来缓冲连接端的数据。内核能够自行管理它。
也不要查看代码中的缓冲区大小。它们毫无意义。也不要使用 DataAvailable 属性,因为如果它返回 false/0,这并不意味着无法读取任何数据。
Connected 属性不一定在两端同步。如果网络出现故障,则无法进行同步。永远不要查看 Connected 属性。如果它在下一个纳秒显示为 true,则它可能为 false。因此不可能根据该属性做出决定。你不需要测试任何东西。只需读/写并通过中止处理异常。
关于数据包,当您Write 时,您并没有发送数据包。 TCP 有一个无边界的字节流。内核在内部打包您的数据。您不需要将数据拆分为特定大小。只需使用相当大的缓冲区大小,例如 8K(或在快速网络上更大)。写入大小只是通过减少聊天来节省 CPU 时间(假设启用了唠叨)。
关于vb.net - 一个TCP连接需要在两端进行哪些 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39063523/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以