接受侦听套接字上的侦听套接字上的连接(并且不再侦听)?
Posted
技术标签:
【中文标题】接受侦听套接字上的侦听套接字上的连接(并且不再侦听)?【英文标题】:Accept connection on a Listening socket on the Listening socket (and no longer listen)? 【发布时间】:2011-12-10 09:40:50 【问题描述】:我正在使用 ICS (TWSocket) 库在 Delphi 6 Pro 中进行套接字编程。我知道我的问题可能看起来令人费解或尴尬,但让我解释一下我的应用程序需求,以便您了解为什么我想做一些违反侦听套接字的通常约定的事情,即断开与新套接字的传入连接由 Accept 方法返回并继续在当前设置的端口上侦听新连接。
在我的应用程序中,我接受来自 Skype 的连接,用于发送和接收与活动 Skype 通话相关的音频缓冲区。问题是当 Skype 连接时,没有握手、识别或身份验证可以让我知道连接的 CALL ID。由于 Skype 可以同时进行电话会议,因此一次可以有多个活动通话。但是,我需要知道哪些套接字连接属于哪个 CALL ID。
由于连接是如上所述的“盲”连接,我可以可靠地将 Skype 套接字连接映射到 CALL ID 的唯一方法是仔细控制我监听的端口号。然后,当我告诉 Skype 将给定 CALL ID 的音频连接到特定端口号时,我知道该套接字上的连接属于该 Skype CALL ID。例如:
-
找到一个可用的端口号,iPortNumber。
将我的套接字设置为监听 iPortNumber
告诉 Skype 将 CALL ID iCallID 连接到端口号 iPortNumber
当我收到 SessionAvailable 事件时,我知道传入的 Skype 连接是针对 CALL ID iCallID。
冲洗并重复我需要处理的每个 CALL ID。我知道这意味着我最终可能会占用一些额外的端口,但由于同时 Skype 通话的数量总是很少,我不认为这是一个问题。我遇到的困难是有一个监听套接字的标准约定,它在新连接进入时使用 Accept 启动一个新套接字。
我想在监听套接字(同一个套接字)上接受连接,然后专门停止监听而不必关闭连接,因为我不想接受该端口上的任何新连接号了。有没有办法做到这一点?
另一种方法是使用 Accept 返回的新创建的套接字,然后关闭侦听套接字,但是我必须想出一个更复杂的方法来跟踪 Skype CALL ID 的端口号,因为如果我是正确的据我所知,Accept 返回的新创建的套接字连接到与侦听套接字不同的端口号,因此侦听套接字可以继续侦听现有端口号。如果可以的话,我想避免这种额外的复杂性和麻烦。
如果有人对如何将我的盲人 Skype 连接映射到与其相关联的 Skype CALL ID 有更好的整体想法/范式,请告诉我。另外,我认为这是不可能的,但是如果有一种聪明的方法可以从与我的应用程序连接在同一系统上的进程中获取传入 Socket 连接背后的进程 ID,我想知道。
【问题讨论】:
【参考方案1】:一次性监听套接字并不少见。例如,FTP 协议使用它们。只需在所需端口上创建一个新的侦听套接字(或让套接字决定它自己的端口,然后您可以检索),将其积压设置为 1,然后对其调用一次 accept()
并关闭它。如果accept()
接受客户端连接,它会返回一个新的套接字句柄,您可以使用该句柄与该客户端进行通信。在此期间,您不需要保持侦听套接字处于活动状态。
我不知道该操作的 ICS 等效项是什么,但在 Indy 中有一个 TIdSimpleServer
组件正是用于此目的(顺便说一下,Windows 上的 Skype 使用 Indy)。
【讨论】:
以上是关于接受侦听套接字上的侦听套接字上的连接(并且不再侦听)?的主要内容,如果未能解决你的问题,请参考以下文章
如何启动 Windows 服务网络进程以侦听 UAC 下普通用户可见的 localhost 套接字上的端口?
事件上的 C++ 侦听器未使用套接字 io C++ 客户端获取事件
为啥 SO_RCVTIMEO 从侦听套接字继承到接受的套接字? [关闭]