tcpsendpacket.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <rtthread.h>
  10. #include <netdb.h> /* 为了解析主机名,需要包含netdb.h头文件 */
  11. #include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
  12. void tcp_senddata(const char *url, int port, int length)
  13. {
  14. struct hostent *host;
  15. int sock, err, result, timeout, index;
  16. struct sockaddr_in server_addr;
  17. rt_uint8_t *buffer_ptr;
  18. /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
  19. host = gethostbyname(url);
  20. /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
  21. if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  22. {
  23. /* 创建socket失败 */
  24. rt_kprintf("Socket error\n");
  25. return;
  26. }
  27. /* 申请内存 */
  28. buffer_ptr = rt_malloc(length);
  29. if(RT_NULL == buffer_ptr)
  30. {
  31. /* 申请内存失败 */
  32. rt_kprintf("No memory\n");
  33. return;
  34. }
  35. /* 构造发送数据 */
  36. for (index = 0; index < length; index ++)
  37. buffer_ptr[index] = index & 0xff;
  38. timeout = 100;
  39. /* 设置发送超时时间100ms */
  40. setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
  41. /* 初始化预连接的服务端地址 */
  42. server_addr.sin_family = AF_INET;
  43. server_addr.sin_port = htons(port);
  44. server_addr.sin_addr = *((struct in_addr *)host->h_addr);
  45. rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
  46. /* 连接到服务端 */
  47. err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
  48. rt_kprintf("TCP thread connect error code: %d\n", err);
  49. while (1)
  50. {
  51. /* 发送数据到sock连接 */
  52. result = send(sock, buffer_ptr, length, MSG_DONTWAIT);
  53. if (result < 0) //数据发送错误处理
  54. {
  55. rt_kprintf("TCP thread send error: %d\n", result);
  56. closesocket(sock);
  57. /* 关闭连接,重新创建连接 */
  58. rt_thread_delay(10);
  59. if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  60. rt_kprintf("TCP Socket error:%d\n", sock);
  61. err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
  62. rt_kprintf("TCP thread connect error code: %d\n", err);
  63. }
  64. else if (result == 0)
  65. {
  66. /* 打印send函数返回值为0的警告信息 */
  67. rt_kprintf("\n Send warning,send function return 0.\r\n");
  68. }
  69. }
  70. }
  71. #ifdef RT_USING_FINSH
  72. #include <finsh.h>
  73. /* 输出tcpclient函数到finsh shell中 */
  74. FINSH_FUNCTION_EXPORT(tcp_senddata, send a packet through tcp connection);
  75. #endif