下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

FreeRTOS_recvfrom()

[FreeRTOS-Plus-TCP API 引用]

FreeRTOS_sockets.h
int32_t FreeRTOS_recvfrom( Socket_t xSocket,
                           void *pvBuffer,
                           size_t xBufferLength,
                           uint32_t ulFlags,
                           struct freertos_sockaddr *pxSourceAddress,
                           socklen_t *pxSourceAddressLength );
		

从 UDP 套接字接收数据(请参阅 FreeRTOS_recv() 了解 TCP 等效项)。 套接字必须已通过成功 成功调用 FreeRTOS_socket() 创建。

此函数可以与标准调用语义或零拷贝 调用语义一起使用:

  • 标准 recvfrom() 语义

    数据从 TCP/IP 堆栈内的网络缓冲区复制到 pvBuffer 参数指向的缓冲区。

    当 ulFlags 参数不存在 FREERTOS_ZERO_COPY 位组时,使用标准 recvfrom() 语义。 请参阅此页面底部的示例和本网站上提供的其他应用程序 示例。

  • 零拷贝 recvfrom() 语义

    应用程序编写者从 TCP/IP 堆栈接收对 已包含已接收的数据的缓冲区 的引用。 没有数据 被复制。

    当 ulFlags 参数存在 FREERTOS_ZERO_COPY 位组时,使用零拷贝 recvfrom() 语义。 请参阅 本页底部的示例以及 本网站上提供的其他应用程序示例。

FreeRTOS_recvfrom() 具有可选超时。 超时默认为 portMAX_DELAY,并使用 FreeRTOS_setsockopt() 进行修改。 如果由于套接字上没有排队等待接收的数据而无法立即完成接收操作, 则 调用的任务将保持为已阻塞状态(以便其他任务RTOS 可以执行),直到接收到任一数据或 超时到期。

FreeRTOS-Plus-TCP [当前]未使用所有函数参数。 未使用的参数保留在函数的原型中, 确保与预期的标准伯克利套接字 API 一致, 并确保与 FreeRTOS-Plus-TCP 的未来版本兼容。

参数:

xSocket   从中读取数据的套接字的句柄。 套接字 必须已被创建(请参阅 FreeRTOS_socket())。

pvBuffer   如果使用标准调用语义(ulFlags 参数未设置 FREERTOS_ZERO_COPY 位),则 pvBuffer 指向 接收数据复制到的缓冲区。

如果使用零拷贝调用语义(ulFlags 参数设置了 FREERTOS_ZERO_COPY 位),则 将 *pvBuffer(通过 FreeRTOS_recvfrom())设置为指向 已保存接收数据的缓冲区。 pvBuffer 用于 从 FreeRTOS_recvfrom() 中传递对接收到数据的引用,而无需复制任何数据。

此页面底部的示例和本网站上提供的其他应用程序 示例演示了 FreeRTOS_recvfrom() 与标准和零拷贝调用 语义一起使用的情况。

xBufferLength   如果使用标准调用语义(ulFlags 参数未设置 FREERTOS_ZERO_COPY 位), 则必须将 xBufferLength 设置为缓冲区的大小(以字节为单位), 指向该缓冲区的是 pvBuffer 参数。

如果使用零拷贝调用语义(ulFlasg 参数未设置 FREERTOS_ZERO_COPY 位), 则 pvBuffer 不指向缓冲区,并且不使用 xBufferLength 。

ulFlags   影响接收操作的一组按位选项。

如果 ulFlags 设置了 FREERTOS_ZERO_COPY 位,则 该函数将使用零拷贝语义,否则 该函数将使用传统拷贝 模式语义。 请参阅上面 pvBuffer 参数的说明。

未来 FreeRTOS-Plus-TCP 版本可以实现其他位。

pxSourceAddress   指向 freertos_sockaddr 结构体的指针, 该结构将(通过 FreeRTOS_recvrom())设置为包含 发送刚接收数据的套接字的 IP 地址和 端口号。 请参阅下面的示例。

pxSourceAddressLength   当前未使用,但应设置为 sizeof (struct freertos_sockaddr),以确保未来的 兼容性。

返回:

如果在配置的块时间到期之前未接收到任何字节,则 返回 -pdFREERTOS_ERRNO_EWOULDBLOCK。

如果套接字未绑定到端口号,则返回 -pdFREERTOS_ERRNO_EINVAL 。

如果套接字接收到信号, 导致读取操作中止,则返回 -pdFREERTOS_ERRNO_EINTR 。

如果成功接收数据,则返回接收的字节数 。

用法示例:

第一个示例接收自套接字,使用标准调用语义(参阅下文 有关使用零拷贝调用语义的另一个示例)。 套接字 被作为函数参数传入,并假定已经 使用 FreeRTOS_socket() 调用创建, 并使用 FreeRTOS_bind() 调用绑定到地址


/* FreeRTOS-Plus-TCP sockets include. */
#include "FreeRTOS_sockets.h"

void vStandardReceiveExample( Socket_t xSocket )
{
/* Note - the RTOS task stack must be big enough to hold this array!. */
uint8_t ucBuffer[ 128 ];
int8_t cIPAddressString[ 16 ];
struct freertos_sockaddr xSourceAddress;
socklen_t xAddressLength = sizeof(xSourceAddress);
int32_t iReturned;

/* Receive into the buffer with ulFlags set to 0, so the FREERTOS_ZERO_COPY bit
is clear. */

iReturned = FreeRTOS_recvfrom(
/* The socket data is being received on. */
xSocket,
/* The buffer into which received data will be
copied. */

ucBuffer,
/* The length of the buffer into which data will be
copied. */

128,
/* ulFlags with the FREERTOS_ZERO_COPY bit clear. */
0,
/* Will get set to the source of the received data. */
&xSourceAddress,
/* Not used but should be set as shown. */
&xAddressLength
);

if( iReturned > 0 )
{
/* Data was received from the socket. Prepare the IP address for

printing to the console by converting it to a string. */

FreeRTOS_inet_ntoa( xSourceAddress.sin_address.ulIP_IPv4, ( char * ) cIPAddressString );
/* FreeRTOS_inet_ntop can be as an alternative to support both IPv4 and IPv6 address */

/* Print out details of the data source. */
printf( "Received %d bytes from IP address %s port number %drn",
iReturned, /* The number of bytes received. */
cIPAddressString, /* The IP address that sent the data. */
FreeRTOS_ntohs( xSourceAddress.sin_port ) ); /* The source port. */
}
}
使用 FreeRTOS_recvfrom() 与零拷贝(和标准相反)调用语义的示例

第二个示例接收自套接字,使用零拷贝调用语义(参阅 上文有关使用标准调用语义的示例)。 套接字 被作为函数参数传入,并假定已经 使用 FreeRTOS_socket() 调用创建, 并使用 FreeRTOS_bind() 绑定到端口号。


/* FreeRTOS-Plus-TCP sockets include. */
#include "FreeRTOS_sockets.h"

void vZeroCopyReceiveExample( Socket_t xSocket )
{
struct freertos_sockaddr xSourceAddress;
socklen_t xAddressLength = sizeof(xSourceAddress);
uint8_t *pucReceivedUDPPayload;
int32_t iReturned;

/* Receive using the zero copy semantics. The address of the

pucReceivedUDPPayload pointer is passed in the pvBuffer parameter. */

iReturned = FreeRTOS_recvfrom(
/* The socket being received from. */
xSocket,
/* pucReceivedUDPPayload will get

set to points to the received data. */

&pucReceivedUDPPayload,
[/code-comment]/* Ignored because the pvBuffer parameter
does not point to a buffer. */[/code-comment]
0,
/* ulFlags with the FREERTOS_ZERO_COPY bit set. */
FREERTOS_ZERO_COPY,
[/code-comment]/* Will get set to the source of the received
data. */[/code-comment]
&xSourceAddress,
/* Not used but should be set as shown. */
&xAddressLength
);

if( iReturned > 0 )
{
/* Data was received from the socket. Convert the IP address to a

string. */

FreeRTOS_inet_ntoa( xSourceAddress.sin_address.ulIP_IPv4, ( char * ) cIPAddressString );
/* FreeRTOS_inet_ntop can be used as an alternative to support both IPv4 and IPv6 address */

/* Print out details of the data source. */
printf( "Received %d bytes from IP address %s port number %drn",
iReturned, /* The number of bytes received. */
cIPAddressString, /* The IP address that sent the data. */
FreeRTOS_ntohs( xSourceAddress.sin_port ) ); /* The source port. */

/* pucReceivedUDPPayload now points to the received data. For

example, *pucReceivedUDPPayload (or pucReceivedUDPPayload[ 0 ]) is the first

received byte. *(pucReceivedUDPPayload + 1 ) (or pucReceivedUDPPayload[ 1 ])

is the second received byte, etc.



The application writer is now responsible for the buffer. To prevent

memory and network buffer leaks the buffer *must* be returned to the IP

stack when it is no longer required
. The following call is used to

return the buffer. */

FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucReceivedUDPPayload );
}
}
使用 FreeRTOS_recvfrom() 与零拷贝(和标准相反)调用语义的示例
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.