下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

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

使用 TCP 套接字发送数据
FreeRTOS-Plus-TCP 网络教程节选

[注意: 本页不介绍供专家用户使用的回调或零拷贝接口 。]

TCP 套接字创建、配置并绑定后, 可使用 FreeRTOS_connect() API 函数连接到远程套接字,或接受 来自远程套接字的连接。 一旦连接, 数据将通过 FreeRTOS_send() API 的功能。

以下源代码显示了创建套接字、 向套接字发送数据然后优雅地关闭套接字的函数。显示的是 IPv4 和 IPv6 用例 。注意 此套接字未显式绑定到端口号——导致它在 FreeRTOS_connect() API 函数时,传递一个指向中断处理函数的指针作为 xFunctionToPend 的参数。

MTU 为 1526 字节开始的 IPv4


void vTCPSend( char *pcBufferToTransmit, const size_t xTotalLengthToSend )
{
Socket_t xSocket;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
TaskHandle_t xRxTask = NULL;
size_t xLenToSend;

/* Set the IP address (192.168.0.200) and port (1500) of the remote socket

to which this client socket will transmit. */

xRemoteAddress.sin_port = FreeRTOS_htons( 1500 );
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 200 );

/* Create a socket. */
xSocket = FreeRTOS_socket( FREERTOS_AF_INET,
FREERTOS_SOCK_STREAM, /* FREERTOS_SOCK_STREAM for TCP. */
FREERTOS_IPPROTO_TCP );
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );

/* Connect to the remote socket. The socket has not previously been bound to

a local port number so will get automatically bound to a local port inside

the FreeRTOS_connect() function. */

if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
{
/* Keep sending until the entire buffer has been sent. */
while( xAlreadyTransmitted < xTotalLengthToSend )
{
/* How many bytes are left to send? */
xLenToSend = xTotalLengthToSend - xAlreadyTransmitted;
xBytesSent = FreeRTOS_send( /* The socket being sent to. */
xSocket,
/* The data being sent. */
&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
/* The remaining length of data to send. */
xLenToSend,
/* ulFlags. */
0 );

if( xBytesSent >= 0 )
{
/* Data was sent successfully. */
xAlreadyTransmitted += xBytesSent;
}
else
{
/* Error - break out of the loop for graceful socket close. */
break;
}
}
}

/* Initiate graceful shutdown. */
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );

/* Wait for the socket to disconnect gracefully (indicated by FreeRTOS_recv()

returning a -pdFREERTOS_ERRNO_EINVAL error) before closing the socket. */

while( FreeRTOS_recv( xSocket, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 )
{
/* Wait for shutdown to complete. If a receive block time is used then

this delay will not be necessary as FreeRTOS_recv() will place the RTOS task

into the Blocked state anyway. */

vTaskDelay( pdTICKS_TO_MS( 250 ) );

/* Note - real applications should implement a timeout here, not just

loop forever. */

}

/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket( xSocket );
}
使用 FreeRTOS_send() 的示例


IPv6 -


void vTCPSend( char *pcBufferToTransmit, const size_t xTotalLengthToSend )
{
Socket_t xSocket;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
TaskHandle_t xRxTask = NULL;
size_t xLenToSend;

/* Set the IP address (2001:470:ed44::9c08:38cc:599f:f62a) and port (1500) of the remote socket

to which this client socket will transmit. */

xRemoteAddress.sin_port = FreeRTOS_htons( 1500 );
FreeRTOS_inet_pton6( "2001:470:ed44::9c08:38cc:599f:f62a", (void *) xRemoteAddress.sin_address.xIP_IPv6.ucBytes )

/* Create a socket. */
xSocket = FreeRTOS_socket( FREERTOS_AF_INET6,
FREERTOS_SOCK_STREAM, /* FREERTOS_SOCK_STREAM for TCP. */
FREERTOS_IPPROTO_TCP );
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );

/* Connect to the remote socket. The socket has not previously been bound to

a local port number so will get automatically bound to a local port inside

the FreeRTOS_connect() function. */

if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
{
/* Keep sending until the entire buffer has been sent. */
while( xAlreadyTransmitted < xTotalLengthToSend )
{
/* How many bytes are left to send? */
xLenToSend = xTotalLengthToSend - xAlreadyTransmitted;
xBytesSent = FreeRTOS_send( /* The socket being sent to. */
xSocket,
/* The data being sent. */
&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
/* The remaining length of data to send. */
xLenToSend,
/* ulFlags. */
0 );

if( xBytesSent >= 0 )
{
/* Data was sent successfully. */
xAlreadyTransmitted += xBytesSent;
}
else
{
/* Error - break out of the loop for graceful socket close. */
break;
}
}
}

/* Initiate graceful shutdown. */
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );

/* Wait for the socket to disconnect gracefully (indicated by FreeRTOS_recv()

returning a -pdFREERTOS_ERRNO_EINVAL error) before closing the socket. */

while( FreeRTOS_recv( xSocket, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 )
{
/* Wait for shutdown to complete. If a receive block time is used then

this delay will not be necessary as FreeRTOS_recv() will place the RTOS task

into the Blocked state anyway. */

vTaskDelay( pdTICKS_TO_MS( 250 ) );

/* Note - real applications should implement a timeout here, not just

loop forever. */

}

/* The socket has shut down and is safe to close. */
FreeRTOS_closesocket( xSocket );
}
使用 FreeRTOS_send() 的示例


<< 返回 RTOS TCP 网络教程索引

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.