2011-10-18 100 views
3

我正在使用ICS(TWSocket)库在Delphi 6 Pro中进行套接字编程。我知道我的问题可能看起来无论是复杂还是尴尬,但让我解释一下我的应用程序需求,以便理解为什么我要做一些违背通常习惯使用侦听套接字的事情,即将传入连接切换到新套接字由Accept方法返回并继续侦听当前设置的端口上的新连接。在侦听套接字上的Listening套接字上接受连接(并且不再侦听)?

在我的应用程序中,我接受来自Skype的连接,用于发送和接收有关Skype通话的音频缓冲区。问题在于,当Skype连接时,没有握手,标识或身份验证,从而无法知道连接的CALL ID。由于Skype可以一起召开电话会议,因此一次可以有多个有效呼叫。但是,我需要知道哪个套接字连接属于哪个CALL ID。

由于连接如上所述是一个“盲”连接,因此我可以可靠地将Skype套接字连接映射到CALL ID的唯一方法是仔细控制我监听的端口号。然后,当我告诉Skype将给定CALL ID的音频连接到特定的端口号时,我知道该套接字上的连接属于该Skype CALL ID。例如:

  1. 查找可用端口号,iPortNumber
  2. 设置我的插座上听iPortNumber
  3. 告诉的Skype到iCallID连接呼叫ID 至端口号iPortNumber
  4. 当我拿到SessionAvailable事件,我知道传入Skype的连接是CALL ID iCallID

冲洗并重复我需要处理的每个CALL ID。我知道这意味着我最终可能会咀嚼一些额外的端口,但由于同时Skype呼叫的数量总是很少,我不认为这是一个问题。我遇到的困难是有一个Listening套接字的标准约定,在新连接进入时使用Accept从新套接字旋转。

我想接受连接on Listening套接字(相同的套接字) ,然后专门停止监听,而不必关闭连接,因为我不想再接受该端口号上的任何新连接。有没有办法做到这一点?

另一种方法是使用由Accept返回的新创建的套接字,然后关闭Listening套接字,但是我必须想出一个更复杂的方法来跟踪Skype CALL ID的端口号,因为如果我是据我所知,由Accept返回的新创建的套接字连接在不同于Listening套接字的端口号上,因此Listening套接字可以继续监听现有的端口号。如果可以的话,我想避免这种额外的复杂性和麻烦。

如果有人对如何将我的盲人Skype连接映射到与他们绑定的Skype CALL ID有更好的总体思路/范例,请告诉我。另外,我不认为这是可能的,但是如果有一个聪明的方法可以从连接到与我的应用程序相同的系统上的进程获取传入Socket连接后面的进程ID,我想知道。

回答

3

一次性侦听套接字并不是那么不寻常。例如,FTP协议使用它们。只需在所需的端口上创建一个新的监听套接字(或让套接字决定它自己的端口,然后可以恢复),将其积压设置为1,然后在其上调用accept()并关闭它。如果accept()接受客户端连接,它将返回一个新的套接字句柄,用于与该客户端进行通信。在此期间,您不需要保持侦听套接字处于活动状态。

我不知道该操作的ICS等价物是什么,但在Indy中有一个用于此目的的TIdSimpleServer组件(顺便说一下,Windows上的Skype使用Indy)。