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() 调用绑定到地址
#include "FreeRTOS_sockets.h"
void vStandardReceiveExample( Socket_t xSocket )
{
uint8_t ucBuffer[ 128 ];
int8_t cIPAddressString[ 16 ];
struct freertos_sockaddr xSourceAddress;
socklen_t xAddressLength = sizeof(xSourceAddress);
int32_t iReturned;
iReturned = FreeRTOS_recvfrom(
xSocket,
ucBuffer,
128,
0,
&xSourceAddress,
&xAddressLength
);
if( iReturned > 0 )
{
FreeRTOS_inet_ntoa( xSourceAddress.sin_address.ulIP_IPv4, ( char * ) cIPAddressString );
printf( "Received %d bytes from IP address %s port number %drn",
iReturned,
cIPAddressString,
FreeRTOS_ntohs( xSourceAddress.sin_port ) );
}
}
使用 FreeRTOS_recvfrom() 与零拷贝(和标准相反)调用语义的示例
第二个示例接收自套接字,使用零拷贝调用语义(参阅
上文有关使用标准调用语义的示例)。 套接字
被作为函数参数传入,并假定已经
使用
FreeRTOS_socket() 调用创建,
并使用
FreeRTOS_bind() 绑定到端口号。
#include "FreeRTOS_sockets.h"
void vZeroCopyReceiveExample( Socket_t xSocket )
{
struct freertos_sockaddr xSourceAddress;
socklen_t xAddressLength = sizeof(xSourceAddress);
uint8_t *pucReceivedUDPPayload;
int32_t iReturned;
iReturned = FreeRTOS_recvfrom(
xSocket,
&pucReceivedUDPPayload,
[/code-comment]/* Ignored because the pvBuffer parameter
does not point to a buffer. */[/code-comment]
0,
FREERTOS_ZERO_COPY,
[/code-comment]/* Will get set to the source of the received
data. */[/code-comment]
&xSourceAddress,
&xAddressLength
);
if( iReturned > 0 )
{
FreeRTOS_inet_ntoa( xSourceAddress.sin_address.ulIP_IPv4, ( char * ) cIPAddressString );
printf( "Received %d bytes from IP address %s port number %drn",
iReturned,
cIPAddressString,
FreeRTOS_ntohs( xSourceAddress.sin_port ) );
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucReceivedUDPPayload );
}
}
使用 FreeRTOS_recvfrom() 与零拷贝(和标准相反)调用语义的示例
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.