楼主: 168321
38 0

[教育经济学基本知识] CAPL学习-UDP API函数 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-7-11
最后登录
2018-7-11

楼主
168321 发表于 2025-11-26 19:16:02 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

UdpOpen

CAPL 函数 ? TCP/IP API ? UdpOpen

该函数用于创建支持无连接、数据报模式通信的 UDP 套接字,支持 IPv4 或 IPv6 地址类型。所有参数均可设置为零值。

当端口参数非零时,套接字会自动绑定到指定端口;若端口为零,则需在后续通过

IpBind
显式绑定,或在调用
UdpSendTo
时由系统分配一个空闲端口进行自动绑定。

注意:如果设置了 IP 地址但端口号为零,不会触发隐式绑定操作。此时必须在套接字打开后手动调用

IpBind
完成绑定。

语法形式

dword UdpOpen( dword ipv4Address, dword port);          // 形式 1  
dword UdpOpen( byte ipv6Address[], dword port);         // 形式 2  
dword UdpOpen( IP_Endpoint localEndpoint);              // 形式 3

作为构造函数使用:

UdpSocket::Open( dword ipv4Address, dword port);         // 形式 1  
UdpSocket::Open( byte ipv6Address[], dword port);        // 形式 2  
UdpSocket::Open( IP_Endpoint localEndpoint );            // 形式 3

参数说明

  • ipv4Address:本地 IPv4 数字地址。设为通配符(如 0.0.0.0)时,表示不限定具体地址,可用于任意网络适配器上的接口。
  • ipv6Address:以 16 字节数组表示的本地 IPv6 地址。与 IPv4 类似,可通过
    IpGetAddressAsArray("::", ipv6AddrArray)
    获取通配符地址。
  • port:主机字节序的端口号。若设为 0,表示不指定端口(使用动态端口)。
  • localEndpoint:指定套接字绑定的本地端点。IP 地址设为通配符时表示不限定特定地址;端口号未定义时,系统将分配一个可用的动态端口。

示例场景

IP_Endpoint(192.168.1.1:4000)
— 绑定至特定 IP 地址和固定端口

IP_Endpoint(0.0.0.0:4000)
— 仅绑定 IPv4 端口

IP_Endpoint([::]:4000)
— 仅绑定 IPv6 端口

IP_Endpoint(192.168.1.1)
— 绑定到指定地址并使用动态端口

返回值说明

INVALID_SOCKET (~0)
:表示函数调用失败,可通过
IpGetLastError
查询具体的错误码。

其他返回值:有效的套接字句柄,表明套接字已成功创建。

版本可用性

版本 支持特性 测量配置 仿真/测试配置
7.0 语法形式 1-2 ?
7.0 SP5 构造函数形式 1-2 ?
12.0 语法/构造函数形式 3 ?

综合示例

variables  
{  
  UdpSocket gSocket;  
  char gRxBuffer[1000];  
}  

on start  
{  
  // 绑定到所有 IPv4 地址的 40001 端口  
  gSocket(192.168.0.2:40002), "Hello", 5 );  
  // 接收数据到缓冲区  
  gSocket.ReceiveFrom( gRxBuffer, elcount(gRxBuffer) );  
}  

// UDP 接收回调函数  
OnUdpReceiveFrom( UdpSocket socket, long result, IP_Endpoint remoteEndpoint, char buffer[], dword size)  
{  
  if (result == 0)  // 接收成功  
  {  
    write( "Received: %s", buffer );  // 输出接收数据  
    // 继续接收下一条数据  
    gSocket.ReceiveFrom( gRxBuffer, elcount(gRxBuffer) );  
  }  
}

UdpClose

CAPL 函数 ? TCP/IP API ? UdpClose

关闭指定的 UDP 套接字。执行成功后,传入的套接字句柄将变为无效状态。

语法

long UdpClose(dword socket);

析构函数形式:

socket.Close();

功能描述

释放与指定套接字关联的资源,并终止其通信能力。

参数

socket
:需要关闭的 UDP 套接字句柄。

返回值

版本支持情况

版本 限制于测量设置 限制于仿真/测试设置
7.0 ?
7.0 SP5(方法) ?

相关参考

可参见“创建 UDP 服务器套接字”的完整示例流程。

UdpConnect

CAPL 函数 ? TCP/IP API ? UdpConnect

语法

long udpConnect(dword socket, IP_Endpoint remoteEndpoint);

方法形式:

long socket.Connect(IP_Endpoint remoteEndpoint);

功能说明

将 UDP 套接字连接至指定的远程端点。一旦完成连接,在发送数据时应使用

UdpSend
而非
UdpSendTo

在服务器端,首次接收来自客户端的数据包时可以建立连接关系,之后可新建未连接的套接字以继续监听新的 UDP 请求(详见示例)。

参数说明

socket
:有效的套接字句柄。

remoteEndpoint
:目标远程端点,需包含目标 IP 地址和端口号。

示例代码片段

IP_Endpoint(192.168.1.1:40001)

IP_Endpoint([FC00::0001]:40001)

返回值

版本兼容性

版本 限制于测量设置 限制于仿真/测试设置
12.0 ?

应用示例

Client.can

variables
{
  UdpSocket gSocket1;
  UdpSocket gSocket2;
  char gBuffer[1500];
}

on start
{
  gSocket1 = UdpSocket::Open(IP_Endpoint(0.0.0.0:0));
  gSocket2 = UdpSocket::Open(IP_Endpoint(0.0.0.0:0));
  gSocket1.Connect(IP_Endpoint(192.168.1.3:40002));
  gSocket2.Connect(IP_Endpoint(192.168.1.3:40002));
}

on key '1'
{
  // 通过已连接的套接字发送数据
  SendCommand(gSocket1, "Request");
  // 等待响应
  gSocket1.ReceiveFrom(gBuffer, elcount(gBuffer));
}

on key '2'
{
  // 通过已连接的套接字发送数据
  SendCommand(gSocket2, "Request");
  // 等待响应
  gSocket1.ReceiveFrom(gBuffer, elcount(gBuffer));
}

on key 'c'
{
  SendCommand(gSocket1, "End");
  gSocket1.Close();
  SendCommand(gSocket2, "End");
  gSocket1.Close();
}

SendCommand(UdpSocket socket, char command[])
{
  socket.Send(command, strlen(command));
}

OnUdpReceiveFrom(dword socket, long result, IP_Endpoint remoteEndpoint, char buffer[], dword size)
{
  // 在此处理服务器响应
}

Server.can

variables
{
  // 用于处理不同连接状态的上下文
  struct connectionContext
  {
    int connectionNumber;
  };
  dword gListeningSocket;
  struct connectionContext connections[long];
  char gBuffer[1500];
  dword gConnectionCount;
}

on start
{
  gConnectionCount = 0;
  // 打开套接字并等待首个数据
  gListeningSocket = UdpOpen(IP_Endpoint(0.0.0.0:40002));
  UdpReceiveFrom(gListeningSocket, gBuffer, elcount(gBuffer));
}

OnUdpReceiveFrom(dword socket, long result, IP_Endpoint remoteEndpoint, char buffer[], dword size)
{
  if (socket == gListeningSocket)
  {
    // 为此连接创建上下文,并打开新套接字等待下一个连接
    UdpConnect(socket, remoteEndpoint);
    connections[socket].connectionNumber = ++gConnectionCount;
    gListeningSocket = UdpOpen(IP_Endpoint(0.0.0.0:40002));
    UdpReceiveFrom(gListeningSocket, gBuffer, elcount(gBuffer));
  }
  AnswerRequest(socket, buffer, size);
}

AnswerRequest(dword socket, char buffer[], dword size)
{
  char response[100];
  if (strncmp(buffer, "Request", size) == 0)
  {
    snprintf(response, elcount(response), "Response for connection #%d", connections[socket].connectionNumber);
    UdpSend(socket, response, strlen(response));
    UdpReceiveFrom(socket, gBuffer, elcount(gBuffer));
  }
  else if (strncmp(buffer, "End", size) == 0)
  {
    connections.remove(socket);
    UdpClose(socket);
  }
}

UdpSend

CAPL 函数 ? TCP/IP API ? UdpSend

语法

long UdpSend(dword socket, char buffer[], dword size);
long UdpSend(dword socket, struct data, dword size);
long UdpSend(dword socket, byte buffer[], dword size);

方法形式:

long socket.Send(char buffer[], dword size);
long socket.Send(struct data, dword size);
long socket.Send(byte buffer[], dword size);

功能描述

通过已连接的 UDP 套接字发送数据。调用此函数前必须先使用

UdpConnect
对套接字进行连接。

参数列表

  • socket
    :目标套接字句柄。
  • buffer
    :指向待发送数据的缓冲区指针。
  • data
    :包含待发送数据的结构体变量。
  • size
    :要发送的数据长度(字节数)。

返回值说明

适用版本

版本 限制于测量设置 限制于仿真/测试设置
12.0 ?

使用示例

variables
{
  UdpSocket gSocket;
}

on start
{
  gSocket = UdpSocket::Open(IP_Endpoint(0.0.0.0:0));
  gSocket.Connect(IP_Endpoint(192.168.1.3:40002));
  gSocket.Send("Request", 7);
}

UdpReceiveFrom

CAPL 函数 ? TCP/IP API ? UdpReceiveFrom

语法

long UdpReceiveFrom(dword socket, char buffer[], dword size);

方法形式:

socket.ReceiveFrom(char buffer[], dword size);

功能说明

从指定的 UDP 套接字接收数据到给定缓冲区中。若当前无法立即完成接收操作,则进入异步模式并返回

SOCKET_ERROR (-1)
。当错误码为
WSA_IO_PENDING (997)
时,系统将在操作最终完成(无论成功或失败)时调用用户实现的回调函数
OnUdpReceiveFrom
(需在同一 CAPL 程序中定义)。

参数说明

  • socket
    :有效的 UDP 套接字句柄。
  • buffer
    :用于存储接收到的数据的缓冲区。
  • size
    :缓冲区的最大容量(单位:字节)。

返回值

版本支持

版本 限制于测量设置 限制于仿真/测试设置
7.0 ?
7.0 SP5(方法) ?

参考示例

请参阅“创建 UDP 服务器套接字”中的完整交互流程。

相关函数

UdpOpen, UdpConnect

OnUdpReceiveFrom

CAPL 函数 ? TCP/IP API ? OnUdpReceiveFrom

功能
当在 CAPL 程序中实现了该回调函数时,会在 UDP 套接字的异步接收操作完成之后自动调用。协议栈内部维护一个数据队列,一旦队列中存在可读取的数据,

UdpReceiveFrom
将立即读取并清空队列中的内容。为了确保后续仍能持续从该套接字接收新的数据,必须在回调函数执行过程中再次调用
UdpReceiveFrom

语法

void OnUdpReceiveFrom(dword socket, long result, dword address, dword port, char buffer[], dword size);  // 形式1  
void OnUdpReceiveFrom(dword socket, long result, dword address, dword port, byte buffer[], dword size);  // 形式2  
void OnUdpReceiveFrom(dword socket, long result, byte ipv6Address[], dword port, char buffer[], dword size);  // 形式3  
void OnUdpReceiveFrom(dword socket, long result, byte ipv6Address[], dword port, byte buffer[], dword size);  // 形式4  
void OnUdpReceiveFrom(dword socket, long result, IP_Endpoint remoteEndpoint, char buffer[], dword size);  // 形式5  
void OnUdpReceiveFrom(dword socket, long result, IP_Endpoint remoteEndpoint, byte buffer[], dword size);  // 形式6

参数说明
socket:标识当前通信的套接字句柄。
result:表示异步操作执行结果的状态码;若值为 0,则表示成功;非零则为错误码。
address:发送方设备的 IPv4 地址(以数值形式表示)。
ipv6Address:发送方设备的 IPv6 地址,采用长度为 16 字节的数组格式。
port:发送方所使用的端口号,使用主机字节序。
buffer:用于存储接收到的数据的缓冲区。
size:实际接收到的数据字节数。
remoteEndpoint:指明发送数据的远程端点信息,包括 IP 和端口。

返回值
无返回值。

可用性
不同版本对本函数的支持情况如下:

版本 支持的形式 限制于测量设置 限制于仿真/测试设置
7.0 形式 1、3 ?
10.0 SP3 形式 2、4 ?
12.0 形式 5、6 ?

示例

variables  
{  
  UdpSocket gSocket;  
  char gRxBuffer[1000];  
}  

on start  
{  
  gSocket = UdpSocket::Open(IP_Endpoint(0.0.0.0:40001));  // 打开 UDP 套接字,绑定到本地端口 40001  
  gSocket.SendTo(IP_Endpoint(192.168.0.2:40002), "Hello", 5);  // 发送数据到远程端点  
  gSocket.ReceiveFrom(gRxBuffer, elcount(gRxBuffer));  // 启动异步接收  
}  

// 回调函数:处理接收完成事件  
OnUdpReceiveFrom(UdpSocket socket, long result, IP_Endpoint remoteEndpoint, char buffer[], dword size)  
{  
  if (result == 0)  // 接收成功  
  {  
    write("Received: %s", buffer);  // 打印接收数据  
    gSocket.ReceiveFrom(gRxBuffer, elcount(gRxBuffer));  // 再次启动异步接收,确保持续接收  
  }  
}

OnUdpSendTo

CAPL 函数 ? TCP/IP API ? OnUdpSendTo

功能
若在 CAPL 程序中定义了此回调函数,则当 UDP 套接字上的异步发送操作完成时,系统将自动触发该函数。

语法

void OnUdpSendTo(dword socket, long result, char buffer[], dword size);

参数说明
socket:对应的套接字句柄。
result:异步发送操作的结果状态码;0 表示成功,其他值代表相应错误。
buffer:本次发送所使用的数据缓冲区。
size:已发送的数据量(单位:字节)。

返回值
无返回值。

可用性
各版本支持情况如下:

版本 限制于测量设置 限制于仿真/测试设置
7.0 ?

示例
可参考“创建 UDP 服务器套接字”中的相关代码实现。

UdpSendTo

CAPL 函数 ? TCP/IP API ? UdpSendTo

功能
用于向指定的目标地址和端口发送数据。如果发送操作不能立即完成,系统将以异步方式执行,并返回

SOCKET_ERROR (-1)
。当错误码为
WSA_IO_PENDING (997)
时,将在操作完成后调用用户实现的回调函数
OnUdpSendTo
(需在同一 CAPL 程序中定义)。同步模式下不会触发回调机制。

语法

// 形式 1-6(基于 IP 地址和端口)
long UdpSendTo(dword socket, dword address, dword port, char buffer[], dword size);          // IPv4,字符缓冲区
long UdpSendTo(dword socket, byte ipv6Address[], dword port, char buffer[], dword size);      // IPv6,字符缓冲区
long UdpSendTo(dword socket, dword address, dword port, struct data[], dword size);          // IPv4,结构体
long UdpSendTo(dword socket, dword address, dword port, byte buffer[], dword size);          // IPv4,字节缓冲区
long UdpSendTo(dword socket, byte ipv6Address[], dword port, struct data[], dword size);      // IPv6,结构体
long UdpSendTo(dword socket, byte ipv6Address[], dword port, byte buffer[], dword size);      // IPv6,字节缓冲区

// 形式 7-9(基于 IP_Endpoint)
long UdpSendTo(dword socket, IP_Endpoint remoteEndpoint, char buffer[], dword size);         // 字符缓冲区
long UdpSendTo(dword socket, IP_Endpoint remoteEndpoint, byte buffer[], dword size);         // 字节缓冲区
long UdpSendTo(dword socket, IP_Endpoint remoteEndpoint, struct data[], dword size);         // 结构体

方法形式
对应上述语法结构,前缀为

socket.SendTo(...)

参数说明

socket
:有效的套接字句柄。
address
:目标设备的 IPv4 地址,采用网络字节序。
ipv6Address
:目标设备的 IPv6 地址,由 16 个字节组成的数组。
port
:目标端口号,使用主机字节序。
buffer
/
data
:待发送数据所在的缓冲区或结构体。
size
:要发送的数据大小(字节数)。
remoteEndpoint
:目标端点配置,需明确指定 IP 地址与端口信息(参见
UdpConnect
示例)。

返回值
:表示函数调用成功。

WSA_INVALID_PARAMETER (87)
:提供的套接字句柄无效。
SOCKET_ERROR (-1)
:函数执行失败。可通过调用
IpGetLastSocketError
获取详细错误信息。若错误码为
997
,表示正在异步发送;其余值则表明发送过程出现错误。

可用性
根据不同软件版本,支持的语法与方法如下:

版本 支持的语法/方法 限制于仿真/测试设置
7.0 语法 1-2 ?
7.0 SP5 方法 1-2 ?
8.2 SP2 语法/方法 3-6 ?
12.0 语法/方法 7-9 ?

示例

variables
{
  UdpSocket gSocket;
  char gRxBuffer[1000];
}

on start
{
  gSocket = UdpSocket::Open(IP_Endpoint(0.0.0.0:40001));
  gSocket.SendTo(IP_Endpoint(192.168.0.2:40002), "Hello", 5);
  gSocket.ReceiveFrom(gRxBuffer, elcount(gRxBuffer));
}

OnUdpReceiveFrom(UdpSocket socket, long result, IP_Endpoint remoteEndpoint, char buffer[], dword size)
{
  if (result == 0)
  {
    write("Received: %s", buffer);
    gSocket.ReceiveFrom(gRxBuffer, elcount(gRxBuffer));
  }
}

相关函数
UdpOpen | UdpClose | UdpReceiveFrom | OnUdpSendTo

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:API APL cap Connections connection

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-5 20:17