当前位置:   article > 正文

RAW 编程接口 TCP 简介

RAW 编程接口 TCP 简介

一、LWIP 中 中 RAW API  编程接口中与 TCP  相关的函数

二、LWIP TCP RAW API 函数

三、LwIP_Periodic_Handle函数

LwIP_Periodic_Handle 函数是一个必须被无限循环调用的 LwIP支持函数,一般在 main函数的无限循环中调用,主要功能是为 LwIP各个模块提供时间并查询链路状态,该 函数有一个形参,用于指示当前时间,单位为 ms。 对于 TCP功能,每 250ms执行一次 tcp_tmr函数;对于 ARP,每 5s 执 行一次 etharp_tmr函数;对于链路状态检测,每 1s 执行一次ETH_CheckLinkStatus 函数; 对于 DHCP功能,每 500ms执行一次 dhcp_fine_tmr函数,如果 DHCP处于DHCP_START 或 DHCP_WAIT_ADDRESS 状态就执行LwIP_DHCP_Process_Handle 函数,对于 DHCP功 能,还有每 60s 执行一次 dhcp_coarse_tmr函数。

四、TCP客户端连接代码

tcpclinet.c

  1. #include "lwip/netif.h"
  2. #include "lwip/ip.h"
  3. #include "lwip/tcp.h"
  4. #include "lwip/init.h"
  5. #include "netif/etharp.h"
  6. #include "lwip/udp.h"
  7. #include "lwip/pbuf.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "main.h"
  11. static void client_err(void *arg, err_t err) //出现错误时调用这个函数,打印错误信息,并尝试重新连接
  12. {
  13. printf("连接错误!!\n");
  14. printf("尝试重连!!\n");
  15. printf("重新初始化客户端\n");
  16. TCP_Client_Init();
  17. }
  18. static err_t client_send(void *arg, struct tcp_pcb *tpcb) //发送函数,调用了tcp_write函数
  19. {
  20. uint8_t send_buf[]= "我是客户端,是你的好哥哥\n";
  21. //发送数据到服务器
  22. tcp_write(tpcb, send_buf, sizeof(send_buf), 1);
  23. return ERR_OK;
  24. }
  25. static err_t client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
  26. {
  27. if (p != NULL)
  28. {
  29. /* 接收数据*/
  30. tcp_recved(tpcb, p->tot_len);
  31. /* 返回接收到的数据*/
  32. tcp_write(tpcb, p->payload, p->tot_len, 1);
  33. memset(p->payload, 0 , p->tot_len);
  34. pbuf_free(p);
  35. }
  36. else if (err == ERR_OK)
  37. {
  38. //服务器断开连接
  39. printf("服务器断开连接!\n");
  40. tcp_close(tpcb);
  41. //重新连接
  42. TCP_Client_Init();
  43. }
  44. return ERR_OK;
  45. }
  46. static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
  47. {
  48. printf("connected ok!\n");
  49. //注册一个周期性回调函数
  50. tcp_poll(pcb,client_send,2);
  51. //注册一个接收函数
  52. tcp_recv(pcb,client_recv);
  53. return ERR_OK;
  54. }
  55. void TCP_Client_Init(void)
  56. {
  57. struct tcp_pcb *client_pcb = NULL; //这一句一定要放在里面,否则会没用
  58. ip4_addr_t server_ip; //因为客户端要主动去连接服务器,所以要知道服务器的IP地址
  59. /* 创建一个TCP控制块 */
  60. client_pcb = tcp_new();
  61. IP4_ADDR(&server_ip, DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);//合并IP地址
  62. printf("客户端开始连接!\n");
  63. //开始连接
  64. tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected);
  65. ip_set_option(client_pcb, SOF_KEEPALIVE);
  66. printf("已经调用了tcp_connect函数\n");
  67. //注册异常处理
  68. tcp_err(client_pcb, client_err);
  69. printf("已经注册异常处理函数\n");
  70. }

tcpclinet.h 

  1. #ifndef _TCPCLIENT_H_
  2. #define _TCPCLIENT_H_
  3. #define TCP_CLIENT_PORT 5001
  4. void TCP_Client_Init(void);
  5. #endif

五、TCP服务器连接代码

tcpserver.c

  1. #include "tcpserver.h"
  2. #include "lwip/netif.h"
  3. #include "lwip/ip.h"
  4. #include "lwip/tcp.h"
  5. #include "lwip/init.h"
  6. #include "netif/etharp.h"
  7. #include "lwip/udp.h"
  8. #include "lwip/pbuf.h"
  9. #include <stdio.h>
  10. #include <string.h>
  11. static err_t tcpecho_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
  12. { //对应接收数据连接的控制块 接收到的数据
  13. if (p != NULL)
  14. {
  15. //int a = 666;
  16. /* 更新窗口*/
  17. tcp_recved(tpcb, p->tot_len); //读取数据的控制块 得到所有数据的长度
  18. /* 返回接收到的数据*/
  19. //tcp_write(tpcb, p->payload, p->tot_len, 1);
  20. uint8_t send_buf1[]= "我收到了你的信息!是";
  21. uint8_t send_buf2[]= "吗?\n";
  22. tcp_write(tpcb, send_buf1, sizeof(send_buf1), 1);
  23. tcp_write(tpcb, p->payload, p->tot_len, 1);
  24. tcp_write(tpcb, send_buf2, sizeof(send_buf2), 1);
  25. memset(p->payload, 0 , p->tot_len);
  26. pbuf_free(p);
  27. }
  28. else if (err == ERR_OK) //检测到对方主动关闭连接时,也会调用recv函数,此时p为空
  29. {
  30. return tcp_close(tpcb);
  31. }
  32. return ERR_OK;
  33. }
  34. static err_t tcpecho_accept(void *arg, struct tcp_pcb *newpcb, err_t err) //由于这个函数是*tcp_accept_fn类型的
  35. //形参的数量和类型必须一致
  36. {
  37. tcp_recv(newpcb, tcpecho_recv); //当收到数据时,回调用户自己写的tcpecho_recv
  38. return ERR_OK;
  39. }
  40. void TCP_Echo_Init(void)
  41. {
  42. struct tcp_pcb *server_pcb = NULL;
  43. /* 创建一个TCP控制块 */
  44. server_pcb = tcp_new();
  45. printf("创建了一个控制块\n");
  46. /* 绑定TCP控制块 */
  47. tcp_bind(server_pcb, IP_ADDR_ANY, TCP_ECHO_PORT);
  48. printf("已经绑定一个控制块\n");
  49. /* 进入监听状态 */
  50. server_pcb = tcp_listen(server_pcb);
  51. printf("进入监听状态\n");
  52. /* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */
  53. tcp_accept(server_pcb, tcpecho_accept); //侦听到连接后,回调用户编写的tcpecho_accept
  54. //这个函数是*tcp_accept_fn类型的
  55. }

tcpserver.h

  1. #ifndef _TCPECHO_H_
  2. #define _TCPECHO_H_
  3. #define TCP_ECHO_PORT 5001
  4. void TCP_Echo_Init(void);
  5. #endif
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/143894?site
推荐阅读
相关标签
  

闽ICP备14008679号