问题标签 [iocp]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
boost - Boost::Asio 的 IOCP CompletionKey?
我正在使用Boost::Asio
. 我必须跟踪每个客户端的数据包时间。当一个 IO 操作完成后,我可以使用GetQueuedCompletionStatus
. 我找不到用Boost::Asio
.
我该如何实现这一点或有其他选择吗?
openssl - AcceptEx 和 OpenSSL
我想知道使用 AcceptEx 和 OpenSSL 处理来自客户端的新连接的正确方法。我有一个非常好的工作服务器,它通过常规 HTTP 使用带有 IO 完成端口的 AcceptEx。我想为其添加 OpenSSL 支持。
我在互联网上阅读了几篇关于将 OpenSSL 与非阻塞套接字一起使用的文章:
- IO 完成端口和 OpenSSL
- http://zzz.zggg.com/2007/12/22/ssl-server-with-openssl-memory-bio-aka-prerequisite-to-asynchronous-openssl/
- http://marc.info/?l=openssl-users&m=99909952822335&w=2
- http://www.lenholgate.com/blog/2002/11/using-openssl-with-asynchronous-sockets.html
他们似乎都没有涉及如何做到这一点,因为他们主要关心连接的客户端。AcceptEx 建立套接字连接并向您返回从客户端发送的第一条数据。我发布的第一个链接讨论了如何使用 IOCP 处理传入数据。到目前为止,我已经尝试过在那里发布的内容,但没有任何运气。基本上我在服务器上看到的内容如下:
- 接收到接受的连接完成。
- 我使用 SSL_new(ctx) 创建 SSL 对象
- 我用 BIO_new(BIO_s_mem()) 创建了输入和输出 BIO 对象。
- 我通过调用 SSL_set_bio(ssl, bioIn, bioOut) 在 SSL 对象中设置 BIO。
- 我调用 SSL_set_accept_state(ssl) 以允许 SSL_read 和 SSL_write 进行协商。
然后我继续尝试处理 AcceptEx 调用读取的第一个数据缓冲区。
- 我调用 BIO_Write(bioIn, buf, len) 将读取的数据复制到 SSL 中。
- 然后,我检查 bioOut 上的待处理握手数据,看看是否需要将其发送回客户端。不过,在接受新连接时,我从未见过 bioOut 中有任何数据。
- 然后我调用 SSL_read(ssl, plainTextBuf, len) 来尝试解密我在第 6 步中放入 bioIn 的数据。这总是返回 -1,而 SSL_get_error 返回 ERROR_SSL_WANT_READ。据我了解,这意味着 bioIn 没有完整的 SSL 记录,因此 SSL 需要来自客户端的更多数据才能解密任何内容。
这是我开始遇到问题的地方,也是我认为我需要一些指导的地方。我已经尝试了很多东西。如果我此时重复调用 SSL_read,它将无限返回 ERROR_SSL_WANT_READ,大概是因为使用内存 BIO 实际上并没有通过套接字进行通信以接收更多数据。我应该发布 WSARecv 调用以等待来自客户端的更多数据吗?
此时我还尝试使用 BIO_read 检查 bioOut 缓冲区,以查看是否有数据需要发送回客户端。确实有一些,我使用 WSASend 将其发回,并发布另一个 WSARecv 调用以等待更多数据(以响应我的发送)。这导致从客户端接收更多数据(WSARecv 在发送完成后完成),因此看起来好像连接正在进行中。但是,当我处理完成的读取时,SSL_read 和 BIO_read 都返回 ERROR_SSL_WANT_READ。所以,我没有足够的数据来解密完整的记录,也没有什么可以发回给客户。发布另一个 WSARecv 调用以响应这种情况也不会从客户端接收更多数据。我不知道 SSL 在这里想要什么。
我现在卡住了,但我会继续尝试更多的东西。如果我发现任何问题,我会用评论更新这个问题。
windows - CloseHandle() 在串口实际关闭之前返回
我正在拉扯我的头发,试图弄清楚串行端口何时完成关闭,以便我可以重新打开它。事实证明,CloseHandle()
在端口实际解锁之前返回。
我正在使用 打开一个串行端口CreateFile(FILE_FLAG_OVERLAPPED)
,使用 将其与 CompletionPort 关联,使用CreateIoCompletionPort()
读取/写入它ReadFile()
,WriteFile()
并使用 关闭它CloseHandle()
。
我注意到,如果我足够快地关闭并重新打开串行端口,我会ERROR_ACCESS_DENIED
从CreateFile()
. 尽管我正在等待CloseHandle()
返回,然后等待与该句柄关联的所有未完成的读/写操作从完成端口返回,但这种情况仍在发生。当然有更好的方法:)
如何同步关闭串口?请不要重试循环、sleep() 或其他一些廉价的黑客。
编辑:也许这与我使用完成端口和 FILE_FLAG_OVERLAPPED 有关。当读/写操作完成时,我会收到一个回调。端口关闭是否有某种回调?
windows - Windows 对每台机器同时打开的套接字/连接数的限制
假设我有一个带有一个真实网络接口和几个环回接口的 Windows 7。我有启用 IOCP 的服务器,它接受来自客户端的连接。我正在尝试尽可能多地模拟与服务器的真实客户端连接。
我的客户端代码只是建立了 X 数量的套接字连接(请注意,客户端绑定到给定的接口):
在环回接口上,我有几个用于绑定的 IP。另外,我也用真实的接口来绑定。当每台机器打开的套接字数量约为 64K 时,我遇到了一个问题:
未处理的异常:System.Net.Sockets.SocketException:无法对套接字执行操作,因为系统缺少足够的缓冲区空间或队列已满
我尝试了一些无助的事情,例如: - 在注册表中将 MaxUserPort 设置为最大值和其他一些推荐的 TCPIP 设置。- 尝试在不同的接口(真实接口和环回)上运行两台服务器并使用多个客户端。
它是 Windows 中的一个已知限制还是有可能以某种方式克服它?
谢谢您的帮助!
c++ - IOCP 和 ReadFileEx 的使用
我在玩 IOCP。我正在尝试编写简单的应用程序来异步从主线程中的文件中读取数据。但是我在 ReadFileEx 函数中遇到错误(ERROR_INVALID_PARAMETER),但似乎我做得很好。我究竟做错了什么?这是我的示例:
io - Win32 IO 完成端口和同步出现的 IO 会发生什么?
根据http://support.microsoft.com/kb/156932,如果满足某些条件,对 ReadFile 的调用可能会出现同步。例如,如果目标文件是 NTFS 压缩的。这篇文章没有说明如果文件句柄与 IOCP 关联会发生什么。
那么当文件句柄与 IOCP 关联时,在这种情况下会发生什么?我是否仍会收到此请求的 IO 完成数据包,还是该请求会完全同步执行?
如果是这样,我必须将整个 ReadFile 调用放在一个工作线程中。最初发出 ReadFile 调用的线程不允许阻塞。我考虑 IOCP 的原因是因为将 ReadFile 调用放入工作线程意味着上下文切换到工作线程,然后在 ReadFile 之后立即阻塞。
c# - 为什么 IOCP 在 BeginExecuteReader 中不起作用
我读过很多文章说 IOCP 用于 BeginXX/EndXX 对调用。但是,当我对它们进行测试时,我的结果显示 IOCP 在 BeginExecuteReader 调用中不起作用,而在 BeginGetResponse 调用中它工作得很好。
我对这个结果感到非常困惑。谁能告诉我原因?我的测试代码有什么问题吗?
这是下面的测试:
使用 BeginGetResponse 进行测试
代码:
结果:
一个 IO 线程用于执行回调。
使用 BeginExecuteReader 代码进行测试:
结果:
另一个工作线程被用来执行回调
有什么问题?
c++ - 如何使用 IOCP 获取客户端真实 IP 地址和端口?
我需要在服务器中获取客户端的 IP 地址和端口。使用 IOCP 在 C++ 上编写的服务器,所以我不接受客户端,我创建新的套接字,然后在这个准备好的套接字上接受(AcceptEx)客户端。因为它 struct sockaddr_in 是不正确的。
我怎样才能做到这一点?
谢谢!
windows - 多核上的 Windows 网络 IOCP 可扩展性
行为如下:例如,一个具有 200 个套接字的服务器工作者每秒处理 100K 回声。在同一个端口上启动另一个服务器工作程序(每个工作程序的套接字数量相同或少一倍,没关系),立即将第一个工作程序的性能降低到大约 50%,并且稍微提高了每台机器的整体性能(每个工作程序服务每秒大约 50K 回波)。
因此,6 核机器的性能与 1 核机器的性能大致相同。
我尝试了不同的方法,例如为每个工作人员设置一个独立的 IOCP 端口(在 CreateIoCompletionPort 中将 NumberOfConcurrentThreads 指定为 1),或者为所有工作人员尝试一个共享的 IOCP 端口(NumberOfConcurrentThreads 等于工作人员的数量),性能是相同的。我的工作人员共享零数据,因此没有锁等。
我希望我遗漏了一些东西,而不是 Windows 内核网络可扩展性问题。我正在使用 Windows 7 企业版 x64。
当然,期望是近似线性扩展性能。
有人知道 IOCP 在一台机器上的多核上的实际可扩展性吗?当活动套接字的数量增加时会出现什么情况?
谢谢!
c - IOCP:没有字节复制的通知
我有 IOCP 应用程序,它为每个套接字上下文存储一个 64kb 缓冲区。它使用大量 RAM,同时处理数千个套接字。相反,我想切换到每个 iocp 线程上下文有一个 64kb 缓冲区的模型(就像我可以在 epoll 和 kqueue 中那样)。为此,我需要我的完成端口能够接收通知,而无需将字节复制到提供的 WSABUF,并且在通知之后只需调用异步 WSARecvFrom(不提供重叠结构,我使用 udp 进行测试),直到我收到 WSAEWOULDBLOCK。我已经读过,如果我为具有重叠结构的 WSARecvFrom 调用提供空的 WSABUF (buf = NULL, len =0),则可以实现以下技术。但它不起作用:IOCP 永远不会“唤醒”,因为缓冲区太小。
还有其他方法可以使这种情况成为可能吗?