Ada GNAT.多个以太网适配器上的套接字发送?

Ada GNAT.多个以太网适配器上的套接字发送?,ada,gnat,Ada,Gnat,我有一台带有4个以太网接口(ensf1s1、ensf1s2、ensf1s3、ensf1f4)的机器,并且使用GNAT。套接字我需要能够通过每个接口发送/接收数据 我使用的代码是 Create_Socket(SendFrom1, Family_Inet, Socket_Datagram); Create_Socket(SendFrom2, Family_Inet, Socket_Datagram); ... Bind_Socket(SendFrom1, SendFrom1Address); Bin

我有一台带有4个以太网接口(ensf1s1、ensf1s2、ensf1s3、ensf1f4)的机器,并且使用GNAT。套接字我需要能够通过每个接口发送/接收数据

我使用的代码是

Create_Socket(SendFrom1, Family_Inet, Socket_Datagram);
Create_Socket(SendFrom2, Family_Inet, Socket_Datagram);
...
Bind_Socket(SendFrom1, SendFrom1Address);
Bind_Socket(SendFrom2, SendFrom2Address);
...
Channel1 := Stream(SendFrom1, SendToAddress1);
Channel2 := Stream(SendFrom2, SendToAddress2);
...
在IP地址配置为192.168.1.(101/102/103/104)的情况下,我通过一个接口接收所有消息,该接口在数据包中正确指定了源和目标IP

我在另一个问题中读到,在同一子网上有多个NIC可能会导致某些操作系统出现问题,因此我改为192.168.1.101、192.168.2.102等,子网掩码为255.255.0.0。使用相同的代码和地址更正,这只发送了用于接口的数据,该接口以前发送了所有消息,但在其他3上没有发送任何消息


我是否在套接字配置中遗漏了一些东西,以确保套接字绑定到具有指定SendFromAddress的适配器?如果相关的话,操作系统是RHEL 7。

您的问题与套接字如何工作有关

如果您将套接字绑定到一个特定的地址,您将只接收该目标地址的数据包。 要从四个接口中的任何一个接收数据包,您可以绑定到INADDR_任意地址。您将按以下方式执行此操作:

Address     : GNAT.Sockets.Sock_Addr_Type;
SendFromAll : GNAT.Sockets.Socket_Type;
   ...
   Address.Port := 0; --  Or whatever fixed port you like
   Address.Addr := GNAT.Sockets.Any_Inet_Addr;
   GNAT.Sockets.Bind_Socket (SendFromAll, Address);
使用此实现,SendFromAll套接字将从任何接口接收数据。使用接收\u套接字,您可以获取发件人地址。然后,当您使用SendFromAll套接字将数据发送回客户端时,系统将根据目标地址和网络路由表选择一个接口。在Linux上,它将取决于路由策略(ip规则)和路由表(ip路由)

现在,如果确实需要将套接字绑定到接口,则必须获取该接口的IP地址。如果您有多个接口,则必须获得它们自己的IP地址。使用GNAT.Sockets没有简单的方法可以做到这一点。您可以使用“按名称获取主机”功能,但必须为每个接口设置不同的名称(否则每个套接字将获得相同的IP)

另一种使用GNAT.Sockets不可能的方法是使用SO_BINDTODEVICE socket选项。将套接字绑定到接口名称(不需要获取IP)


您可能遇到的情况是,您正在为每个绑定\u套接字调用使用相同的IP地址。

您的问题与套接字如何工作有关

如果您将套接字绑定到一个特定的地址,您将只接收该目标地址的数据包。 要从四个接口中的任何一个接收数据包,您可以绑定到INADDR_任意地址。您将按以下方式执行此操作:

Address     : GNAT.Sockets.Sock_Addr_Type;
SendFromAll : GNAT.Sockets.Socket_Type;
   ...
   Address.Port := 0; --  Or whatever fixed port you like
   Address.Addr := GNAT.Sockets.Any_Inet_Addr;
   GNAT.Sockets.Bind_Socket (SendFromAll, Address);
使用此实现,SendFromAll套接字将从任何接口接收数据。使用接收\u套接字,您可以获取发件人地址。然后,当您使用SendFromAll套接字将数据发送回客户端时,系统将根据目标地址和网络路由表选择一个接口。在Linux上,它将取决于路由策略(ip规则)和路由表(ip路由)

现在,如果确实需要将套接字绑定到接口,则必须获取该接口的IP地址。如果您有多个接口,则必须获得它们自己的IP地址。使用GNAT.Sockets没有简单的方法可以做到这一点。您可以使用“按名称获取主机”功能,但必须为每个接口设置不同的名称(否则每个套接字将获得相同的IP)

另一种使用GNAT.Sockets不可能的方法是使用SO_BINDTODEVICE socket选项。将套接字绑定到接口名称(不需要获取IP)


可能发生的情况是,您对每个Bind\u套接字调用使用相同的IP地址。

如果子网掩码为255.255.255.0,则更改的地址将仅位于不同的子网上。如果子网掩码为255.255.255.0,则更改的地址将仅位于不同的子网上。