jjzjj

c++ - 为什么socket()、connect()、send()等有WSA挂件,closesocket()没有?

coder 2023-06-04 原文

我将尝试用几个例子来解释我的意思:

  • socket() -> WSASocket()
  • connect() -> WSAConnect()
  • send() -> WSASend()
  • sendto() -> WSASendTo()
  • recv() -> WSARecv()
  • recvfrom() -> WSARecvFrom()
  • ...
  • closesocket() -> WSA???()

这没什么大不了的,但仍然让我头疼。

最佳答案

要理解这一点,您必须意识到 Winsock 是在 1990 年代初期创建的,当时 Windows 3.x 恐龙在地球上漫游。

Windows 套接字(“Winsock”)API 反射(reflect)了大多数 BSD 套接字 API:两者都提供给定的功能,都做同样的事情。因此,socket() 是两个 API 下的相同调用。地方有细微差别,但没有比其他基于 BSD 套接字的系统(如 Linux 和 OS X)在网络编程上的差异更大的了。

除了实现通用的基础 API 之外,Winsock API 还提供了许多 BSD 套接字的扩展。许多函数的名称与原始函数相似,但带有 WSA 前缀和驼峰式大小写。这些是原始功能的纯粹扩展版本,而不是它们的替代品。您可以根据是否需要扩展功能以及您的程序是否必须可移植到仅提供 BSD 套接字 API 的系统来选择使用哪一个。例如,WSASocket() 采用与 socket() 相同的参数以及与其他 Winsock 扩展有关的三个附加参数。如果您不需要扩展,调用 socket() 并没有真正的惩罚,而且您还可以获得可移植性的好处。

除了这些简单的扩展之外,还有一些没有直接 BSD 等效的 Winsock 扩展,例如 WSAAsyncSelect()。与 Unixy 系统的程序相比,这些通常与 Windows 程序的编写方式不同有关。在这种特殊情况下,WSAAsyncSelect() 的存在使编写使用套接字的单线程 GUI 程序更容易,而网络 I/O 不会阻塞 GUI,或者反之亦然。这在今天很有用,但对于 Winsock 在 Windows 3.1 时代的成功绝对至关重要,因为它没有线程或其他有用的多处理和 IPC 机制。

只剩下一些奇怪的东西,比如 closesocket()ioctlsocket()

closesocket()close(2)在 POSIX/Unix 下,除了它只需要套接字,而不是文件句柄。这是更名的部分原因,但真正的原因来 self 在上面提到的 1990 年代早期的历史问题。在那些日子里,一些 Windows 编译器——有 more available then比今天 - 包括 POSIX API 等价物,以简化将代码从其他平台移植到 Windows。这些功能非常有限,并且不包括套接字支持,但是,close() 函数名称当时在 Windows 上被认为是“采用”的。这不再是真的,但 Winsock 是其历史的产物,现在无法改变。

ioctlsocket()ioctl() 的故事类似。一个很大的区别是 ioctlsocket() 在 Windows 上的功能与 ioctl() 在 Unix 系统上的功能相比受到很大限制。它的存在只是为了向 Windows 提供一些与网络相关的设施,最初的 Winsock 创建者认为这些设施在 BSD 套接字 API 中很有用。多年来,您可以在 Unixy 系统上使用套接字和 ioctl() 而不能使用 ioctlsocket() 的大部分功能已通过其他 API 添加到 Windows,只有一个其中是 WSAIoctl().

我为 The History of Winsock 写了一篇关于“Winsock Programmer's FAQ”的文章。 (我坚持)这会更详细地说明这一切。另一篇相关文章是“BSD Sockets Compatibility。”

关于c++ - 为什么socket()、connect()、send()等有WSA挂件,closesocket()没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3255899/

有关c++ - 为什么socket()、connect()、send()等有WSA挂件,closesocket()没有?的更多相关文章

  1. 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

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  7. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  8. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  9. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐