IpJoinMulticastGroup
函数
在指定套接字上加入多播组,以便接收多播消息。
语法
long IpJoinMulticastGroup(dword socket, dword ifIndex, dword ipv4address); // 形式1long IpJoinMulticastGroup(dword socket, dword ifIndex, byte ipv6Address[]); // 形式2long IpJoinMulticastGroup(dword socket, dword ifIndex, IP_Address multicastAddress); // 形式3
构造函数形式
long socket.JoinMulticastGroup(dword ifIndex, dword ipv4address); // 形式1long socket.JoinMulticastGroup(dword ifIndex, byte ipv6Address[]); // 形式2long socket.JoinMulticastGroup(dword ifIndex, IP_Address multicastAddress); // 形式3
说明
- 接收多播消息前需先加入多播组。
- 离开多播组需调用
IpLeaveMulticastGroup。 - 发送多播消息前需调用
IpSetMulticastInterface。
注意
- 依赖所选协议栈,不支持操作系统TCP/IP栈。
参数
socket:套接字句柄。ifIndex:1-based网络接口索引(操作系统栈含本地回环地址,CANoe栈含VLAN地址)。ipv4address:目标IPv4地址(数值形式)。ipv6Address:目标IPv6地址(16字节数组)。multicastAddress:IP多播地址。
返回值
0:成功。WSA_INVALID_PARAMETER (87):接口索引无效。SOCKET_ERROR (-1):失败,需调用IpGetLastSocketError获取详细错误码。
可用性
- 版本8.2支持形式1-2,版本12.0支持形式3;仅适用于仿真/测试环境。
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
gSocket = UdpSocket::Open(IP_Endpoint(0.0.0.0:40001));
gSocket.JoinMulticastGroup(1, IP_Address(239.0.0.123));
}
on key '2'
{
gSocket.LeaveMulticastGroup(1, IP_Address(239.0.0.123));
}
IpLeaveMulticastGroup
函数
在指定套接字上离开已加入的多播组,停止接收多播消息。
语法
long IpLeaveMulticastGroup(dword socket, dword ifIndex, dword ipv4address); // 形式1long IpLeaveMulticastGroup(dword socket, dword ifIndex, byte ipv6Address[]); // 形式2long IpLeaveMulticastGroup(dword socket, dword ifIndex, IP_Address multicastAddress); // 形式3
构造函数形式
long socket.LeaveMulticastGroup(dword ifIndex, dword ipv4address); // 形式1long socket.LeaveMulticastGroup(dword ifIndex, byte ipv6Address[]); // 形式2long socket.LeaveMulticastGroup(dword ifIndex, IP_Address multicastAddress); // 形式3
说明
- 需先通过
IpJoinMulticastGroup加入组。 - 发送多播消息前需调用
IpSetMulticastInterface。
注意
- 依赖所选协议栈,不支持操作系统TCP/IP栈。
参数 (同 IpJoinMulticastGroup)
返回值 (同 IpJoinMulticastGroup)
可用性 (同 IpJoinMulticastGroup)
示例 (同 IpJoinMulticastGroup)
IpRemoveAdapterAddress
函数
从指定索引的网络接口中移除IP地址。
语法
long IpRemoveAdapterAddress(dword ifIndex, dword ipv4address, dword ipv4mask); // 形式1long IpRemoveAdapterAddress(dword ifIndex, byte ipv6Address[], dword prefix); // 形式2long IpRemoveAdapterAddress(dword ifIndex, IP_Address address, dword prefix); // 形式3
注意
- 依赖所选协议栈,不支持操作系统TCP/IP栈。
参数
ifIndex:1-based网络接口索引。ipv4address:待移除的IPv4地址。ipv4mask:IPv4子网掩码(网络字节序)。ipv6Address:待移除的IPv6地址(16字节数组)。prefix:IPv6前缀长度。address:待移除的IP地址。
返回值 (同 IpJoinMulticastGroup)
可用性
- 版本8.1支持形式1-2,版本12.0支持形式3;仅适用于仿真/测试环境。
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
ipAddAdapterAddress(1, IP_Address(192.168.0.116), 24);
gSocket = UdpSocket::Open(IP_Endpoint(192.168.0.116:40016));
gSocket.SendTo(IP_Endpoint(192.168.0.255:40255), "Hello", 5);
}
on preStop
{
ipRemoveAdapterAddress(1, IP_Address(192.168.0.116), 24);
}
IPRouteAddGateway
函数
向TCP/IP栈路由表添加静态网关路由。
语法
long IPRouteAddGateway(dword destination, dword mask, dword gateway); // 形式1long IPRouteAddGateway(byte destination[], dword prefix, byte gateway[]); // 形式2long IPRouteAddGateway(IP_Address destination, dword prefix, IP_Address gateway); // 形式3
说明
- 根据掩码(IPv4)或前缀(IPv6)添加主机或网络路由。
- 匹配目标地址的数据包将通过指定网关发送。
参数
destination:目标IP地址。mask:IPv4子网掩码(全1表示主机路由)。prefix:IPv6前缀长度(128表示主机路由)。gateway:网关IP地址。
返回值
0:成功。WSA_INVALID_PARAMETER (87):参数无效。SOCKET_ERROR (-1):失败,需调用IpGetLastError获取详细错误码。
可用性
- 版本10.0 SP4支持形式1-2,版本12.0支持形式3;仅适用于以太网仿真/测试环境。
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
ipRouteAddGateway(IP_Address(192.168.1.0), 24, IP_Address(192.168.0.200));
gSocket = UdpSocket::Open(IP_Endpoint(192.168.0.19:40019));
gSocket.SendTo(IP_Endpoint(192.168.1.123:40123), "Hello", 5); // 通过网关发送
}
on preStop
{
ipRouteDeleteGateway(IP_Address(192.168.1.0), 24);
}
IPRouteAddHost
函数
向TCP/IP栈接口路由表添加静态主机路由,跳过ARP请求/邻居发现。
语法
long IPRouteAddHost(dword hostAddr, byte macId[]); // 形式1long IPRouteAddHost(byte hostAddr[], byte macId[]); // 形式2long IPRouteAddHost(IP_Address hostAddr, qword macId); // 形式3
说明
- 需先存在接口或网络路由(可通过
IPRouteAddInterface添加)。
参数
hostAddr:目标主机IP地址。macId:目标MAC地址(数组或64位数值)。
返回值 (同 IPRouteAddGateway)
可用性 (同 IPRouteAddGateway)
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
ipRouteAddHost(IP_Address(192.168.0.190), ethGetMacAddressAsNumber("02:00:00:00:00:BE"));
gSocket = UdpSocket::Open(IP_Endpoint(192.168.0.18:40018));
gSocket.SendTo(IP_Endpoint(192.168.0.190:40190), "Hello", 5); // 直接使用静态MAC
}
on preStop
{
ipRouteDeleteHost(IP_Address(192.168.0.190));
}
IPRouteAddInterface
函数
向TCP/IP栈添加静态接口路由,指定目标地址通过特定接口发送。
语法
long IPRouteAddInterface(dword destination, dword mask, dword ifIndex); // 形式1long IPRouteAddInterface(byte destination[], dword prefix, dword ifIndex); // 形式2long IPRouteAddInterface(IP_Address destination, dword prefix, dword ifIndex); // 形式3
参数
ifIndex:接口索引。
返回值 (同 IPRouteAddGateway)
可用性 (同 IPRouteAddGateway)
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
ipRouteAddInterface(IP_Address(192.168.100.0), 24, 2); // 接口2路由至192.168.100.0/24
gSocket = UdpSocket::Open(IP_Endpoint(192.168.0.20:40020));
gSocket.SendTo(IP_Endpoint(192.168.100.100:40100), "Hello", 5); // 通过接口2发送
}
on preStop
{
ipRouteDeleteInterface(IP_Address(192.168.100.0), 24);
}
IPRouteDeleteGateway
函数
从TCP/IP栈路由表删除网关路由。
语法
long IPRouteDeleteGateway(dword dest, dword mask); // 形式1long IPRouteDeleteGateway(byte dest[], dword prefix); // 形式2long IPRouteDeleteGateway(IP_Address destination, dword prefix); // 形式3
参数 (同 IPRouteAddGateway)
返回值 (同 IPRouteAddGateway)
可用性 (同 IPRouteAddGateway)
示例 (见 IPRouteAddGateway)
IPRouteDeleteHost
函数
从TCP/IP栈删除静态主机路由。
语法
long IPRouteDeleteHost(dword hostAddr); // 形式1long IPRouteDeleteHost(byte hostAddr[]); // 形式2long IPRouteDeleteHost(IP_Address hostAddr); // 形式3
参数
hostAddr:目标主机IP地址。
返回值 (同 IPRouteAddGateway)
可用性 (同 IPRouteAddGateway)
示例 (见 IPRouteAddHost)
版本信息:Version 14 SP2 © Vector Informatik GmbH
1. IPRouteDeleteInterface
CAPL 函数 >> TCP/IP API >> IPRouteDeleteInterface
函数
该函数用于从 TCP/IP 协议栈的路由表中删除指向某个接口的路由。
语法
capl
long IPRouteDeleteInterface(dword dest, dword mask); // 形式 1
long IPRouteDeleteInterface(byte dest[], dword prefix); // 形式 2
long IPRouteDeleteInterface(IP_Address destination, dword prefix); // 形式 3
参数
- destination:路由的 IPv4 或 IPv6 目的地址。
- mask:IPv4 地址的子网掩码。若为全 1 掩码,则删除单主机接口路由;否则删除网络接口路由。
- prefix:IPv6 目的地址的前缀长度。若前缀为 128,则删除单主机接口路由;否则删除网络接口路由。
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):参数无效。
- SOCKET_ERROR (-1) :函数执行失败,可调用
IpGetLastError获取详细错误码。
可用性
| 版本 | 支持形式 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|---|
| 10.0 SP4 | 形式 1-2 | Ethernet | --- | • |
| 12.0 | 形式 3 | Ethernet | --- | • |
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
ipRouteAddInterface(IP_Address(192.168.100.0), 24, 2);
gSocket = UdpSocket::Open(IP_Endpoint(192.168.0.20:40020));
// 由于目的地址位于其他子网,UDP 数据包将通过上述配置的接口发送
gSocket.SendTo(IP_Endpoint(192.168.100.100:40100), "Hello", 5);
}
on preStop
{
ipRouteDeleteInterface(IP_Address(192.168.1.0), 24); // 删除路由
}
IpSetAdapterGateway
CAPL 函数 >> TCP/IP API >> IpSetAdapterGateway
函数
设置默认网关地址。系统仅支持一个默认网关,新设置将覆盖旧网关。默认网关必须位于网络协议栈配置的子网中,否则协议栈无法找到网关路由。删除网关时,可将地址设为 0.0.0.0(IPv4)或 ::(IPv6)。
语法
capl
long IpSetAdapterGateway(dword ifIndex, dword ipv4address); // 形式 1
long IpSetAdapterGateway(dword ifIndex, byte ipv6Address[]); // 形式 2
long IpSetAdapterGateway(dword ifIndex, IP_Address address); // 形式 3
注意
- 函数依赖于所选协议栈,且无法与操作系统 TCP/IP 协议栈配合使用。
参数
- ifIndex :基于 1 的网络接口索引。默认网关虽在指定接口上设置,但对整个协议栈生效。
- 操作系统协议栈会考虑所有适配器地址(含环回地址),顺序取决于系统适配器列表。
- CANoe 协议栈会考虑所有分配的地址(含 VLAN 地址)。
- ipv4address:网关的 IPv4 数值地址。
- ipv6Address:网关的 IPv6 地址(16 字节数组)。
- address:网关的 IP 地址。
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):网络接口索引无效。
- SOCKET_ERROR (-1) :函数执行失败,可调用
IpGetLastSocketError获取详细错误码。
可用性
| 版本 | 支持形式 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|---|
| 8.1 | 形式 1-2 | --- | --- | • |
| 12.0 | 形式 3 | --- | --- | • |
示例
capl
variables
{
UdpSocket gSocket;
}
on start
{
ipSetAdapterGateway(1, IP_Address(192.168.0.200)); // 设置网关
gSocket = UdpSocket::Open(IP_Endpoint(192.168.0.17:40017));
// 发送请求的目的地址位于其他子网,UDP 数据包将发送至网关的 MAC 地址
gSocket.SendTo(IP_Endpoint(192.168.1.100:40100), "Hello", 5);
}
IpSetAdapterMacId
CAPL 函数 >> TCP/IP API >> IpSetAdapterMacId
函数
设置指定接口的 MAC 地址。
语法
capl
long IpSetAdapterMacId(dword ifIndex, qword macId);
参数
- ifIndex :基于 1 的网络接口索引。
- 操作系统协议栈会考虑所有适配器地址(含环回地址),顺序取决于系统适配器列表。
- CANoe 协议栈会考虑所有分配的地址(含 VLAN 地址)。
- macId:MAC 地址(qword 类型)。
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):参数无效。
可用性
| 版本 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|
| 13.0 | Ethernet | --- | • |
示例
capl
on start
{
dword result;
dword channel = 1;
dword ifIndex;
qword macId;
ifIndex = ipGetAdapter(channel);
if(ifIndex > 0)
{
macId = ethGetMacAddressAsNumber("02:11:22:33:44:55"); // 将 MAC 地址转换为数值
result = ipSetAdapterMacId(ifIndex, macId);
if(result != 0)
{
write("接口 %d 的 ipSetAdapterMacId 失败", ifIndex);
}
}
else
{
write("通道 %d 未找到接口", channel);
}
}
IPSetAdapterStatus
CAPL 函数 >> TCP/IP API >> IPSetAdapterStatus
注意
仅当使用独立 TCP/IP 协议栈实例或 CANoe TCP/IP 协议栈时可用。
函数
激活或停用 TCP/IP 协议栈的网络适配器。适配器停用后,其所有 IP 地址将被移除,且无法收发数据包;重新激活后,TCP/IP 协议栈对话框中配置的地址将重新生效,默认网关也会恢复。
语法
capl
long IPSetAdapterStatus(dword ifIndex, dword status);
参数
- ifIndex:基于 1 的网络接口索引。
- status :
0:停用适配器1:激活适配器
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):参数无效。
- SOCKET_ERROR (-1) :函数执行失败,可调用
IpGetLastError获取详细错误码。
可用性
| 版本 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|
| 11.0 | IP | --- | • |
IpSetMulticastInterface
CAPL 函数 >> TCP/IP API >> IpSetMulticastInterface
函数
设置发送组播消息的接口。若不调用此函数,指定套接字无法发送组播消息。接收组播消息前需通过 IpJoinMulticastGroup 加入组播组,离开时调用 IpLeaveMulticastGroup。
语法
capl
long IpSetMulticastInterface(dword socket, dword ifIndex);
// 方法形式
long socket.SetMulticastInterface(dword ifIndex);
注意
- 函数依赖于所选协议栈,且无法与操作系统 TCP/IP 协议栈配合使用。
参数
- socket:套接字句柄。
- ifIndex :基于 1 的网络接口索引。
- 操作系统协议栈会考虑所有适配器地址(含环回地址),顺序取决于系统适配器列表。
- CANoe 协议栈会考虑所有分配的地址(含 VLAN 地址)。
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):网络接口索引无效。
- SOCKET_ERROR (-1) :函数执行失败,可调用
IpGetLastSocketError获取详细错误码。
可用性
| 版本 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|
| 8.2 | --- | --- | • |
示例
capl
variables
{
const dword IPV4_STR_SIZE = 16; // IPv4 字符串长度
const dword INVALID_SOCKET = ~0; // 无效套接字
constant dword udpMulticastSocket = INVALID_SOCKET; // 组播套接字
dword port = 12345; // 目标 UDP 端口
dword ifIdx = 1; // 接口索引
dword ipv4MulticastAddr; // IPv4 组播地址
char ipv4MulticastAddrStr[IPV4_STR_SIZE] = "224.123.111.222"; // IPv4 组播地址字符串
}
on start
{
long result;
ipv4MulticastAddr = IpGetAddressAsNumber(ipv4MulticastAddrStr); // 转换为数值地址
udpMulticastSocket = UdpOpen(0, 0); // 打开 UDP 套接字
if (udpMulticastSocket != INVALID_SOCKET)
{
result = IpSetMulticastInterface(udpMulticastSocket, ifIdx); // 设置组播接口
if (result == 0)
{
write("套接字 %d 已设置为在适配器 %d 上发送组播 %s", udpMulticastSocket, ifIdx, ipv4MulticastAddrStr);
write("向 %s:%d 发送组播消息...", ipv4MulticastAddrStr, port);
UdpSendTo(udpMulticastSocket, ipv4MulticastAddr, port, "a", 1);
UdpSendTo(udpMulticastSocket, ipv4MulticastAddr, port, "b", 1);
UdpSendTo(udpMulticastSocket, ipv4MulticastAddr, port, "c", 1);
}
else
{
writeLineEx(1, 3, "IpSetMulticastInterface: 错误 %d", result);
}
}
else
{
writeLineEx(1, 3, "UdpOpen: 套接字打开失败");
}
}
on preStop
{
UdpClose(udpMulticastSocket); // 关闭套接字
}
IpSetSocketOption
CAPL 函数 >> TCP/IP API >> IpSetSocketOption
函数
修改套接字选项。
语法
capl
// 函数形式
long IpSetSocketOption(dword socket, long level, long name, long value); // 形式 1
long IpSetSocketOption(dword socket, char level[], char name[], long value); // 形式 2
// 方法形式
socket.SetSocketOption(long level, long name, long value); // 形式 1
socket.SetSocketOption(char level[], char name[], long value); // 形式 2
参数
- socket:套接字句柄。
- level :选项定义的级别,例如
SOL_SOCKET(0xFFFF)。详见"套接字选项"获取支持的级别。 - name :要修改的选项名称,例如
SO_BROADCAST(0x0020)。详见"套接字选项"获取支持的选项。 - value:选项值。
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):套接字无效。
- SOCKET_ERROR (-1) :函数执行失败,可调用
IpGetLastError获取详细错误码。
可用性
| 版本 | 支持形式/方法 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|---|
| 7.0 | 函数形式 1 | --- | --- | • |
| 7.0 SP5 | 方法形式 1 | --- | --- | • |
| 8.2 SP2 | 函数/方法形式 2 | --- | --- | • |
示例
capl
on start
{
CHAR errorMessage[255];
LONG tcpSocket;
LONG result;
LONG value;
// 打开 TCP 套接字
tcpSocket = tcpOpen(0, 0);
if(tcpSocket == ~0)
{
write("TCP 套接字打开失败,最后错误: %d", ipGetLastError());
}
// 激活 SO_KEEPALIVE 选项
result = ipSetSocketOption(tcpSocket, "SOL_SOCKET", "SO_KEEPALIVE", 1);
if(result != 0)
{
ipGetLastSocketErrorAsString(tcpSocket, errorMessage, elcount(errorMessage));
write("设置 SO_KEEPALIVE 失败: %s", errorMessage);
}
// 调整 IP_TTL 值(若大于 32)
result = ipGetSocketOption(tcpSocket, "IPPROTO_IP", "IP_TTL", value);
if(result != 0)
{
ipGetLastSocketErrorAsString(tcpSocket, errorMessage, elcount(errorMessage));
write("获取 IP_TTL 失败: %s", errorMessage);
}
if(value > 32)
{
result = ipSetSocketOption(tcpSocket, "IPPROTO_IP", "IP_TTL", 32);
if(result != 0)
{
ipGetLastSocketErrorAsString(tcpSocket, errorMessage, elcount(errorMessage));
write("设置 IP_TTL 失败: %s", errorMessage);
}
}
// 禁用 Nagle 算法
result = ipSetSocketOption(tcpSocket, "IPPROTO_TCP", "TCP_NODELAY", 1);
if(result != 0)
{
ipGetLastSocketErrorAsString(tcpSocket, errorMessage, elcount(errorMessage));
write("设置 TCP_NODELAY 失败: %s", errorMessage);
}
// 连接套接字
result = tcpConnect(tcpSocket, IpGetAddressAsNumber("192.168.1.2"), 21);
if(result != 0)
{
ipGetLastSocketErrorAsString(tcpSocket, errorMessage, elcount(errorMessage));
write("连接失败: %s", errorMessage);
}
}
IpSetStackParameter
CAPL 函数 >> TCP/IP API >> IpSetStackParameter
函数
修改 TCP/IP 协议栈的全局行为或接口行为。参数名称以点分隔的路径形式表示。
支持的参数
- canoe.interface.mtu:修改接口的最大传输单元(MTU),范围 72--1500 字节,需指定接口索引。
- canoe.ipv6.default_scope:设置 IPv6 协议栈的默认作用域(目的地址为链路本地地址时使用)。
- net.inet.tcp.delayed_ack:启用/禁用 TCP 延迟确认算法(默认启用,ACK 会尽可能随响应数据包捎带发送)。
- net.inet.tcp.rfc1323:启用/禁用 RFC1323 定义的 TCP 时间戳选项(CANoe 12.0 起默认启用)。
- net.inet.tcp.rexmit_max:配置 TCP 连接的最大重传超时。
- net.inet.tcp.hostcache.purgenow:清除 TCP 主机缓存中收集的所有 metrics(如现有路由的慢启动阈值)。
语法
capl
long IpSetStackParameter(char parameterName[], long value);
long IpSetStackParameter(dword ifIndex, char parameterName[], long value);
注意
- 函数依赖于所选协议栈,且无法与操作系统 TCP/IP 协议栈配合使用。
参数
- ifIndex:基于 1 的网络接口索引(部分参数需指定)。
- parameterName :参数路径字符串(如
net.inet.tcp.delayed_ack)。 - value:参数值。
返回值
- 0:函数执行成功。
- WSA_INVALID_PARAMETER (87):网络接口索引无效。
- SOCKET_ERROR (-1) :函数执行失败,可调用
IpGetLastError获取详细错误码。
可用性
| 版本 | 限制 | 测量设置 | 仿真/测试设置 |
|---|---|---|---|
| 9.0 | IP | --- | • |
示例
capl
on start
{
LONG result;
LONG ifIndex;
LONG value;
// 修改接口 MTU
ifIndex = 1;
value = 1460;
result = ipSetStackParameter(ifIndex, "canoe.interface.mtu", value);
if(result != 0)
{
writeLineEx(1, 3, "接口 %d MTU 设置失败(%d 字节),结果: %d", ifIndex, value, result);
}
else
{
writeLineEx(1, 0, "接口 %d MTU 设置为 %d 字节", ifIndex, value);
}
// 设置 IPv6 默认作用域
ifIndex = 1;
result = ipSetStackParameter(ifIndex, "canoe.ipv6.default_scope", 1);
if(result != 0)
{
writeLineEx(1, 3, "接口 %d IPv6 默认作用域设置失败,结果: %d", ifIndex, result);
}
else
{
writeLineEx(1, 0, "接口 %d IPv6 默认作用域设置完成", ifIndex);
}
// 禁用 TCP 延迟确认
value = 0;
result = ipSetStackParameter("net.inet.tcp.delayed_ack", value);
if(result != 0)
{
writeLineEx(1, 3, "延迟确认行为修改失败,结果: %d", result);
}
else
{
if(value == 0)
{
writeLineEx(1, 0, "TCP 延迟确认已禁用");
}
else
{
writeLineEx(1, 0, "TCP 延迟确认已启用");
}
}
}