/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-9 shchl first version
*/#include"includes.h"#if1#defineTCP_CLIENT_STACK_SIZE4096/*任务栈大小*/#defineTCP_CLIENT_PRIORITY4/*优先级*/#definePACKET_SIZE1536/*数据包大小*/#definePOOL_SIZE((sizeof(NX_PACKET)+ PACKET_SIZE)*16)/*数据包池大小(16个缓冲区)*/#defineTCP_LOCAL_IPIP_ADDRESS(192,168,8,9)/*本地ip*/#defineTCP_LOCAL_PORT8000#defineTCP_LOCAL_SUB_MASHIP_ADDRESS(255,255,255,0)/*本地ip*/#defineTCP_SERVER_PORT8080#defineTCP_SEVER_IPIP_ADDRESS(192,168,8,2)static ULONG error_counter;static NX_IP tcp_client_ip;static TX_THREAD tcp_client_thread;static NX_PACKET_POOL tcp_client_packet_pool;static NX_TCP_SOCKET client_socket;staticvoidtcp_client_entry(ULONG input);staticinlinevoidstatus_check(UINT stat){if(stat){
error_counter++;// todo}}intapp_task_tcp_client_thread_create(){
UINT status;/* Create the main thread. */tx_thread_create(&tcp_client_thread,"tcp client thread",
tcp_client_entry,0,app_malloc(TCP_CLIENT_STACK_SIZE),
TCP_CLIENT_STACK_SIZE,
TCP_CLIENT_PRIORITY,
TCP_CLIENT_PRIORITY,
TX_NO_TIME_SLICE,
TX_AUTO_START);/* Create a packet pool. */
status =nx_packet_pool_create(&tcp_client_packet_pool,"NetX Main Packet Pool",
PACKET_SIZE,app_malloc(POOL_SIZE),
POOL_SIZE);status_check(status);/* Create an IP instance. */
status =nx_ip_create(&tcp_client_ip,"ip instance",
TCP_LOCAL_IP,
TCP_LOCAL_SUB_MASH,&tcp_client_packet_pool,
nx_stm32_eth_driver,app_malloc(2048),2048,1);status_check(status);/* Enable ARP and supply ARP cache memory for IP Instance 0. */
status =nx_arp_enable(&tcp_client_ip,app_malloc(1024),1024);/* Check ARP enable status. */status_check(status);/* Enable ICMP */
status =nxd_icmp_enable(&tcp_client_ip);status_check(status);/* Enable TCP processing for both IP instances. */
status =nx_tcp_enable(&tcp_client_ip);status_check(status);return NX_SUCCESS;}staticvoidtcp_client_release_resource(NX_TCP_SOCKET *socket_ptr);static UINT tcp_client_build_connection(NX_TCP_SOCKET *socket_ptr, NXD_ADDRESS *server_addr);staticvoidtcp_client_entry(ULONG input){NX_PARAMETER_NOT_USED(input);
UINT status;
NX_PACKET *my_packet;
ULONG length;
NXD_ADDRESS server_ipv4_address;
ULONG actual_status;/* 确保 IP 实例已初始化。 */do{/* 等待 1 秒钟,让 内部 IP 线程完成其初始化。. */
status =nx_ip_status_check(&tcp_client_ip,
NX_IP_INITIALIZE_DONE,&actual_status,
NX_IP_PERIODIC_RATE);}while(status != NX_SUCCESS);/* set the TCP server addresses. */
server_ipv4_address.nxd_ip_version = NX_IP_VERSION_V4;
server_ipv4_address.nxd_ip_address.v4 = TCP_SEVER_IP;/* Loop to repeat things over and over again! */while(1){/*建立连接*/do{tx_thread_sleep(1000);/*建立连接失败等待1s*/
status =tcp_client_build_connection(&client_socket,&server_ipv4_address);}while(status);/*和服务端通讯(todo 业务逻辑切入点)*/{
retry_send:
status =nx_packet_allocate(&tcp_client_packet_pool,&my_packet,
NX_TCP_PACKET,
NX_WAIT_FOREVER);#defineSEND_DATA"hello server, i is client"/* Check status. */if(status != NX_SUCCESS){tx_log("Error nx_packet_allocate: 0x%x\n", status);break;}/* Write ABCs into the packet payload! */nx_packet_data_append(my_packet,
SEND_DATA,sizeof(SEND_DATA),&tcp_client_packet_pool,
TX_WAIT_FOREVER);
status =nx_packet_length_get(my_packet,&length);if((status)||(length !=sizeof(SEND_DATA))){
error_counter++;}/* Send the packet out! */
status =nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE);/* Determine if the status is valid. */if(status){
error_counter++;tx_log("send error:%#x\r\n", status);nx_packet_release(my_packet);}else{tx_thread_sleep(200);goto retry_send;}}/*释放相关资源*/tcp_client_release_resource(&client_socket);}}NET_X_APP_EXPORT(app_task_tcp_client_thread_create);// 建立连接static UINT tcp_client_build_connection(NX_TCP_SOCKET *socket_ptr, NXD_ADDRESS *server_addr){
UINT status;/* Create a socket. */
status =nx_tcp_socket_create(&tcp_client_ip, socket_ptr,"Client Socket",
NX_IP_NORMAL,
NX_FRAGMENT_OKAY,
NX_IP_TIME_TO_LIVE,
PACKET_SIZE,
NX_NULL,
NX_NULL);status_check(status);/* Bind the socket. */
status =nx_tcp_client_socket_bind(socket_ptr, TCP_LOCAL_PORT, NX_WAIT_FOREVER);status_check(status);/* Attempt to connect the socket. */
status =nxd_tcp_client_socket_connect(socket_ptr, server_addr, TCP_SERVER_PORT, NX_IP_PERIODIC_RATE);if(status){// 连接失败,清理资源tcp_client_release_resource(socket_ptr);}return status;}// 资源释放staticvoidtcp_client_release_resource(NX_TCP_SOCKET *socket_ptr){
UINT status =0;/*socket 状态处于已经建立连接或等待关闭,则需要关闭连接*/if(socket_ptr->nx_tcp_socket_state == NX_TCP_ESTABLISHED || socket_ptr->nx_tcp_socket_state == NX_TCP_CLOSE_WAIT){
status =nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE);}/* Determine if the status is valid. */if(status){tx_log("nx_tcp_socket_disconnect error:%#x\r\n", status);
error_counter++;}/* Unbind the socket. */
status =nx_tcp_client_socket_unbind(&client_socket);/* Check for error. */if(status){tx_log("nx_tcp_client_socket_unbind error:%#x\r\n", status);
error_counter++;}/* Delete the socket. */
status =nx_tcp_socket_delete(&client_socket);/* Check for error. */if(status){tx_log("nx_tcp_socket_delete error:%#x\r\n", status);
error_counter++;}}#endif