WSAConnect()和ConnectEx()的区别

5

我在客户端使用IOCP,但是我发现在连接到服务器时使用阻塞调用更加方便。那么在使用IOCP时,使用阻塞的WSAConnect()而不是非阻塞的ConnectEx()是否存在问题?


3
如果您想进行同步I/O,为什么要使用IOCP? - Mat
@Veronika Prüssels:“@Mat 如果我理解正确,OP只关心连接调用是否会阻塞,出于方便考虑。” 是的,这就是我想要的。 “@OP 没有什么可以阻止您将ConnectEx与阻塞future和promise混合使用,并使用IOCP,同时仍然获得阻塞行为。” 这是什么意思?! - user6088487
@Mat,希望连接本身是同步的,而读写是异步的,这是可以接受的。是的,这很奇怪,但在某些罕见的情况下,这种做法是有意义的。 - David Haim
1个回答

5

没问题。
调用WSAConnect会阻塞线程直到连接被创建或者产生错误。之后,你可以使用异步IO,并通过应用程序IOCP获得有关已完成数据包的通知。但是IOCP不会提供有关WSAConnect的任何数据包。

另一个要注意的点是,IOCP仅适用于重叠IO。如果你的函数没有消耗OVERLAPPED结构体的任何内存位置(比如WSAConnect),你可以确信IOCP不会与该API调用打交道。即使提供了OVERLAPPED,也不意味着操作是异步的并且将在IOCP中发布。

你可能想看看C++的Boost.Asio和C的libuv。这样代码也将具有可移植性(而且不容易出错)。另一个有趣的平台是Microsoft的Casablanca,它是跨平台的,但根据我的经验,性能非常差。


即使提供了OVERLAPPED,也不意味着操作是异步的并将在IOCP中发布。您的意思是什么?您的意思是我可以例如调用WSARecv()并传递一个OVERLAPPED结构而不接收完成数据包吗? - user6088487
如果文件句柄未打开异步操作,则ReadFileWriteFile将获取OVERLAPPED,该结构指定从文件的哪个偏移量开始读取。在这种情况下,该操作将同步完成。 - David Haim
此外,您需要明确将 Handle 关联到 IOCP 中以接收 IO 数据包。因此,总结一下,您需要满足以下条件才能启动 IOCP:1)拥有支持异步 IO 的 Handle;2)将 Handle 与 IOCP 关联;3)使用消耗 OVERLAPPED 结构的函数。如果其中一个条件不适用,则 IOCP 将无法为该函数启动。 - David Haim
我有一个最后的问题:如果我的套接字支持异步IO,并且我已经将套接字与完成端口关联,那么在这种情况下,在套接字上使用阻塞的WSAConnect()仍然没有问题,对吗? - user6088487
是的。正如我所说,由于WSAConnect没有使用OVERLAPPED,因此IOCP不会监控它。但这个函数仍然可以正常工作。 - David Haim
在同一套接字上混合使用阻塞的WSASend()和WSARecv()调用与异步IOCP调用也完全没有问题 - 当然不是同时进行!这虽然不寻常,但它可以正常工作。 - Len Holgate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接