2023-05-30 08:53:31 +00:00
/*
* 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
*/
/*
* Copyright ( c ) 2006 - 2018 , RT - Thread Development Team
*
* SPDX - License - Identifier : Apache - 2.0
*
* Change Logs :
* Date Author Notes
*
*/
/*
* 程 序 清 单 : tcp 客 户 端
*
* 这 是 一 个 tcp 客 户 端 的 例 程
* 导 出 tcpclient 命 令 到 控 制 终 端
* 命 令 调 用 格 式 : tcpclient URL PORT
* URL : 服 务 器 地 址 PORT : : 端 口 号
* 程 序 功 能 : 接 收 并 显 示 从 服 务 端 发 送 过 来 的 信 息 , 接 收 到 开 头 是 ' q ' 或 ' Q ' 的 信 息 退 出 程 序
*/
# include <rtthread.h>
# include <sys/socket.h> /* 使用BSD socket, 需要包含socket.h头文件 */
# include <netdb.h>
# include <string.h>
# include <finsh.h>
# define BUFSZ 1024
2023-06-11 08:32:09 +00:00
static const char send_data [ ] = { 0x88 , 0xAA , 0xBB , 0x88 , 0x00 , 0x01 , 0x00 , 0x00 , 0x10 , 0xA0 , 0x00 , 0x10 , 0x00 , 0x31 , 0x33 , 0x39 , 0x32 , 0x00 , 0x10 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01 , 0x00 } ; //"This is TCP Client from RT-Thread."; /* 发送用到的数据 */
2023-05-30 08:53:31 +00:00
void tcpclient ( int argc , char * * argv )
{
int ret ;
char * recv_data ;
struct hostent * host ;
int sock , bytes_received ;
struct sockaddr_in server_addr ;
const char * url ;
int port ;
if ( argc < 3 )
{
rt_kprintf ( " Usage: tcpclient URL PORT \n " ) ;
2023-06-06 07:45:13 +00:00
rt_kprintf ( " Like: tcpclient 10.10.10.72 8005 \n " ) ;
2023-05-30 08:53:31 +00:00
return ;
}
url = argv [ 1 ] ;
port = strtoul ( argv [ 2 ] , 0 , 10 ) ;
/* 通过函数入口参数url获得host地址( 如果是域名, 会做域名解析) */
host = gethostbyname ( url ) ;
/* 分配用于存放接收数据的缓冲 */
recv_data = rt_malloc ( BUFSZ ) ;
if ( recv_data = = RT_NULL )
{
rt_kprintf ( " No memory \n " ) ;
return ;
}
/* 创建一个socket, 类型是SOCKET_STREAM, TCP类型 */
if ( ( sock = socket ( AF_INET , SOCK_STREAM , 0 ) ) = = - 1 )
{
/* 创建socket失败 */
rt_kprintf ( " Socket error \n " ) ;
/* 释放接收缓冲 */
rt_free ( recv_data ) ;
return ;
}
/* 初始化预连接的服务端地址 */
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 )
{
/* 连接失败 */
rt_kprintf ( " Connect fail! \n " ) ;
closesocket ( sock ) ;
/*释放接收缓冲 */
rt_free ( recv_data ) ;
return ;
}
while ( 1 )
{
2023-06-11 08:32:09 +00:00
/* 发送数据到sock连接 */
ret = send ( sock , send_data , sizeof ( send_data ) , 0 ) ;
if ( ret < 0 )
{
/* 发送失败,关闭这个连接 */
closesocket ( sock ) ;
rt_kprintf ( " \n send error,close the socket. \r \n " ) ;
rt_free ( recv_data ) ;
break ;
}
else if ( ret = = 0 )
{
/* 打印send函数返回值为0的警告信息 */
rt_kprintf ( " \n Send warning,send function return 0. \r \n " ) ;
}
2023-05-30 08:53:31 +00:00
/* 从sock连接中接收最大BUFSZ - 1字节数据 */
bytes_received = recv ( sock , recv_data , BUFSZ - 1 , 0 ) ;
if ( bytes_received < 0 )
{
/* 接收失败,关闭这个连接 */
closesocket ( sock ) ;
rt_kprintf ( " \n received error,close the socket. \r \n " ) ;
/* 释放接收缓冲 */
rt_free ( recv_data ) ;
break ;
}
else if ( bytes_received = = 0 )
{
/* 默认 recv 为阻塞模式, 此时收到0认为连接出错, 关闭这个连接 */
closesocket ( sock ) ;
rt_kprintf ( " \n received error,close the socket. \r \n " ) ;
/* 释放接收缓冲 */
rt_free ( recv_data ) ;
break ;
}
/* 有接收到数据,把末端清零 */
recv_data [ bytes_received ] = ' \0 ' ;
if ( strncmp ( recv_data , " q " , 1 ) = = 0 | | strncmp ( recv_data , " Q " , 1 ) = = 0 )
{
/* 如果是首字母是q或Q, 关闭这个连接 */
closesocket ( sock ) ;
rt_kprintf ( " \n got a 'q' or 'Q',close the socket. \r \n " ) ;
/* 释放接收缓冲 */
rt_free ( recv_data ) ;
break ;
}
else
{
/* 在控制终端显示收到的数据 */
2023-06-11 08:32:09 +00:00
for ( size_t var = 0 ; var < bytes_received ; + + var ) {
rt_kprintf ( " %02X " , recv_data [ var ] ) ;
}
// rt_kprintf("\nReceived data = %02X ", recv_data);
2023-06-06 07:45:13 +00:00
closesocket ( sock ) ;
// rt_kprintf("\n got a 'q' or 'Q',close the socket.\r\n");
/* 释放接收缓冲 */
rt_free ( recv_data ) ;
break ;
2023-05-30 08:53:31 +00:00
}
2023-06-11 08:32:09 +00:00
}
2023-05-30 08:53:31 +00:00
return ;
}
MSH_CMD_EXPORT ( tcpclient , a tcp client sample ) ;