/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-05-30 murmur the first version */ #include #include /* 使用BSD socket,需要包含socket.h头文件 */ #include #include #define LOG_TAG "ttTR" #define LOG_LVL LOG_LVL_DBG #include #include #define BUFSZ 200 #define RETRYCNT 10 #define URL TTIP #define PORT 8005 static int sock=0; void tcpClose(void) { /* 关闭这个连接 */ if (sock) { closesocket(sock); } } int tcpInit(void) { int ret; const char *url = URL; int port = PORT; /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ struct hostent *host; host = gethostbyname(url); /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* 创建socket失败 */ LOG_E("Socket error"); return RT_ERROR; } /* 初始化预连接的服务端地址 */ struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr = *((struct in_addr *)host->h_addr); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); /* 连接到服务端 */ if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { /* 连接失败 */ LOG_E("Connect fail!\n"); tcpClose(); return RT_ERROR; } else { return RT_EOK; } } static int tcpSend(const rt_uint8_t *send_data, size_t len) { // LOG_HEX("send",27,send_data,len); /* 发送数据到sock连接 */ int ret = send(sock, send_data, len, 0); if (ret == len) { ret = RT_EOK; } else { LOG_E("Send error, send function return %d", ret); ret = RT_ERROR; } return ret; } /** * 接收TCP数据 * @param recv_data 接收数据缓存,最小200字节 * @return 接收到的数据长度,-1表示发生了错误。 */ int tcpRec(unsigned char *recv_data) { int ret=RT_ERROR; /* 从sock连接中接收最大BUFSZ字节数据 */ int bytes_received = recv(sock, recv_data, BUFSZ, 0); if (bytes_received) { return bytes_received; } else { LOG_E("received error."); return -RT_ERROR; } } /** * 发送数据时TT的ack信号 * @return */ static int tcpAck() { /* 分配用于存放接收数据的缓冲 */ char *recv_data; recv_data = rt_malloc(BUFSZ); if (recv_data == RT_NULL) { LOG_E("No memory."); return RT_ENOMEM; } int ret=RT_ERROR; size_t cnt = RETRYCNT;//尝试次数 while (cnt--) { /* 从sock连接中接收最大BUFSZ - 1字节数据 */ int bytes_received = recv(sock, recv_data, BUFSZ, 0); if (bytes_received) { LOG_HEX("rec data",16,recv_data,bytes_received); //check response rt_uint8_t rec_good[] = { 0x88, 0xAA, 0xBB, 0x88 };//前四字节 if (rt_memcmp(recv_data, rec_good, 4)) { ret = RT_EOK; /* 释放接收缓冲 */ rt_free(recv_data); break; } } else { LOG_E("received error."); /* 释放接收缓冲 */ rt_free(recv_data); break; } rt_thread_delay(100); } return ret; } /** * 发送一维数组 * @param msg 待发数据 * @param len 数组长度 * @return 成功返回0 */ int sendMsg(const rt_uint8_t *msg, size_t len) { // if (tcpInit() != RT_EOK) // { // return RT_ERROR; // } if (tcpSend(msg, len) != RT_EOK) { tcpClose(); return RT_ERROR; } // if (tcpRec() != RT_EOK) // { // tcpClose(); // return RT_ERROR; // }; // tcpClose(); return RT_EOK; } /** * 发送二维数组 * @param msg 待发二维数组 * @param s 各纬度数组长度 * @param row 数组长度 * @return 成功返回0 */ int sendMsgs(const rt_uint8_t (*msg)[200], char *s, size_t row) { int ret = RT_EOK; if (tcpInit() != RT_EOK) { ret = RT_ERROR; return ret; } for (size_t var = 0; var < row; var++) { if (tcpSend(msg[var], s[row]) != RT_EOK) { ret = RT_ERROR; break; } #ifdef CHK_ACK if (tcpAck() != RT_EOK) { ret = RT_ERROR; break; }; #endif } tcpClose(); return ret; }