FreeRTOS_sockets.h
int32_t FreeRTOS_sendto( Socket_t xSocket,
const void *pvBuffer,
size_t xTotalDataLength,
uint32_t ulFlags,
const struct freertos_sockaddr *pxDestinationAddress,
socklen_t xDestinationAddressLength );
发送数据至 UDP 套接字(请参阅 FreeRTOS_send(),
了解 TCP 等效项)。 套接字必须已通过
成功调用 FreeRTOS_socket() 创建。
此函数可以与标准调用语义或零拷贝
调用语义:
-
标准 sendto() 语义
数据从 pvBuffer
参数指向的地址复制到 TCP/IP 堆栈内部分配的网络缓冲区。
当 ulFlags
参数不存在 FREERTOS_ZERO_COPY 位组时,使用标准 sendto() 语义。
请参阅此页面底部的示例和本网站上提供的其他应用程序
示例。
-
零拷贝 sendto() 语义
应用程序编写者:
-
从 TCP/IP 堆栈获取缓冲区。
-
将待发送数据写入
从 TCP/IP 堆栈获得的缓冲区。
-
将指向(已完成的)缓冲区的指针用作
pvBuffer 参数。
然后,TCP/IP 堆栈会通过
TCP/IP 堆栈将对同一缓冲区的引用传递给以太网驱动器,并在那进行传输
(通常在硬件允许的情况下通过 DMA 传输)。
当 ulFlags
参数存在 FREERTOS_ZERO_COPY 位组时,使用零拷贝 sendto() 语义。 请参阅
本页底部的示例以及
本网站上提供的其他应用程序示例。
FreeRTOS_sendto() 具有可选超时。 该超时默认为
ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME,
可使用 FreeRTOS_setsockopt() 进行修改。
如果发送操作不能立即排队发送字节,那么
调用 任务将被保持在阻塞状态(以执行其他任务RTOS
),直至可排队发送字节,或
超时到期。 以下情况会发生超时:
-
使用标准 sendto() 语义,且 TCP/IP 堆栈
无法及时获取网络缓冲区。 或,
-
队列中无可用空间向
IP 任务发送消息(请参阅RTOS
FreeRTOSIPConfig.h 头文件中的 ipconfigEVENT_QUEUE_LENGTH 设置)。
如果 FreeRTOS_sendto() 在一个套接字上被调用,
且该套接字未绑定到一个移植
号,且 ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 值
在 FreeRTOSIPConfig.h 中设置为 1,则 TCP/IP 堆栈会自动将该套接字
与私有地址范围中的一个移植号绑定。
FreeRTOS -Plus- TCP [当前]未使用所有函数参数。
未使用的参数保留在函数的原型中,
确保与预期的标准伯克利套接字 API 一致,
并确保与 FreeRTOS-Plus-TCP 的未来版本兼容。
参数:
xSocket
|
接收发送数据的套接字的句柄。 套接字
必须已被创建(请参阅
FreeRTOS_socket())。
|
pvBuffer
|
如果正在使用标准调用语义(ulFlags
参数不存在 FREERTOS_ZERO_COPY 位组),
则 pvBuffer 指向正被传输的数据
的数据源。 FreeRTOS_sendto() 将从 pvBuffer
拷贝数据至 TCP/IP 堆栈内的网络缓冲区。
如果正在使用零拷贝调用语义(ulFlags
参数存在 FREERTOS_ZERO_COPY 位组),
则 pvBuffer 指向此前从
TCP/IP 堆栈获得的缓冲区,且该缓冲区已包含正在发送的数据。
TCP/IP 堆栈会控制该缓冲区,
而非拷贝缓冲区数据。
请参阅以下示例用法内容和本网站提供的应用程序
示例。
|
xTotalDataLength
|
待发送的字节数。
|
ulFlags
|
一组影响发送操作的逐位选项。
如果 ulFlags 存在 FREERTOS_ZERO_COPY 位组,
则函数会使用零拷贝语义,
否则函数会使用标准拷贝模式语义。
请参阅上面 pvBuffer 参数的说明。
未来 FreeRTOS-Plus-TCP 版本可以实现其他位。
|
pxDestinationAddress
|
指向 freertos_sockaddr 结构体的指针,
包含目标 IP 地址和移植号(
接收被发送数据的套接字)。 请参阅以下示例。
|
xDestinationAddressLength
|
当前未使用,但应设置为
sizeof (struct freertos_sockaddr),以确保未来的
兼容性。
|
返回:
实际排队发送的字节数,
如果发生错误或超时,则为 0。
注意,因为 FreeRTOS 未实现 errno,
在出现错误时的行为必然与 sendto() 函数的行为不同,
后者完全符合预期的伯克利
套接字行为。
用法示例:
第一个示例使用标准调用语义向套接字发送数据(请参阅
以下另一使用零拷贝调用语义的示例)。 套接字
被作为函数参数传入,并假定已经
通过调用 FreeRTOS_socket() 创建。 如果 ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 在
FreeRTOSIPConfig.h 中未设置为 1,那么套接字也被认为已经
使用 FreeRTOS_bind() 绑定到移植号上。
#include "FreeRTOS_sockets.h"
void vStandardSendExample( Socket_t xSocket )
{
uint8_t ucBuffer[ 128 ];
struct freertos_sockaddr xDestinationAddress;
int32_t iReturned;
xDestinationAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 100 );
xDestinationAddress.sin_port = FreeRTOS_htons( 1024 );
memset( ucBuffer, 0xff, 128 );
iReturned = FreeRTOS_sendto(
xSocket,
ucBuffer,
128,
0,
&xDestinationAddress,
sizeof( xDestinationAddress )
);
if( iReturned == 128 )
{
}
}
Example using FreeRTOS_sendto() with the standard (as opposed to zero copy) calling semantics
第二个示例使用零拷贝调用语义向套接字发送数据(请参阅
以上另一使用标准调用语义的示例)。 套接字
被作为函数参数传入,并假定已经
通过调用 FreeRTOS_socket() 创建。 如果 ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 在
FreeRTOSIPConfig.h 中未设置为 1,那么套接字也被认为已经
使用 FreeRTOS_bind() 绑定到移植号上。
#include "FreeRTOS_sockets.h"
void vZeroCopySendExample( Socket_t xSocket )
{
struct freertos_sockaddr xDestinationAddress;
uint8_t *pucUDPPayloadBuffer;
int32_t iReturned;
xDestinationAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 100 );
xDestinationAddress.sin_port = FreeRTOS_htons( 1024 );
pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( 128,
portMAX_DELAY );
if( pucUDPPayloadBuffer != NULL )
{
memset( pucUDPPayloadBuffer, 0xff, 128 );
iReturned = FreeRTOS_sendto(
xSocket,
&xBufferDescriptor,
128,
FREERTOS_ZERO_COPY,
&xDestinationAddress,
sizeof( xDestinationAddress )
);
if( iReturned != 0 )
{
}
else
{
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
}
}
}
Example using FreeRTOS_sendto() with the zero copy calling semantics
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.