服务器活动时如何绑定新服务器绑定

How to bind new server binding while server active

如何让 OS 在服务器处于活动状态时将可用端口分配给 Indy 服务器中的新绑定?

  IdUDPServer.Active := True;

  for I := 0 to 4 do
  begin
    IdUDPServer.Bindings.add;
  end;

  for I := 0 to IdUDPServer.Bindings.Count-1 do
  begin
    WriteLn(IdUDPServer.Bindings[I].Port);
  end; 

将打印以下内容:

40371
0
0
0
0
0

我试试这个

var
  H : TIdSocketHandle; 
  ...
  for I := 0 to 4 do
  begin
    H := IdUDPServer.Bindings.add;
    try
      H.Bind;
    except
      On E: Exception do
        WriteLn(e.Message);
    end;
  end; 
  ...

我得到以下信息:

Socket Error # 9
Bad file number.
Socket Error # 9
Bad file number.
Socket Error # 9
Bad file number.
Socket Error # 9
Bad file number.
Socket Error # 9
Bad file number.
56554
0
0
0
0
0

有没有办法在不停用和响应服务器的情况下完成此操作?

因为我不想在添加新绑定时失去任何活跃的客户端。

目前,当 1 处于活动状态时,您无法向 TIdUDPServer 添加新的侦听端口。它根本不允许这样做(与 TIdTCPServer 相比)。 TIdUDPServer 的侦听端口仅在其 Active 属性 从 False 切换为 True 时打开。

1:好吧,你可以随心所欲地调用 Bindings.Add(),但是新的绑定在 TIdUDPServer 中不会有任何效果。

当您调用 Bindings.Add() 时,它会将服务器的 DefaultPort 分配给新的 TIdSocketHandle 对象的 Port 属性。 DefaultPort 默认为 0。但是要真正打开 TIdSocketHandle.Port 来侦听数据包需要先停用 TIdUDPServer

如果可以访问,调用 TIdSocketHandle.Bind() 会更新 TIdSocketHandle.Port(因此允许您绑定到端口 0 以分配可用的临时端口),但是您使用 Bind() 的方式不会工作是因为您没有事先调用 TIdSocketHandle.AllocateSocket(),所以 TIdSocketHandle.HandleBind() 使用无效。但是即使你确实让 Bind() 工作了,它仍然对你没有帮助,因为 TIdUDPServer 只有在 Active 属性 切换为 True,因此当服务器已经处于活动状态时您添加到 Bindings 的任何新 TIdSocketHandle 对象将不会读取数据包以提供给您的 OnUDPRead 事件处理程序。

所以,如果要修改TIdUDPServer中的Bindings端口,必须先设置Active=False,然后根据需要修改,再设置Active=True。我已经为您向 Indy 的问题跟踪器添加了增强请求:

#294: Update TIdUDPServer to allow updating Bindings while active

请注意,UDP 是无连接的,因此您不会像在 TCP 中那样 "lose clients",除非您的 UDP 客户端设计为在其侦听端口被报告时停止向您的服务器发送数据包OS 在发送数据包时关闭。