【lwip】第二篇:使用lwip的netconn接口编写TCP服务器

一、netconn介绍

  参考链接:https://lwip.fandom.com/wiki/Netconn_API
  netconn API 是一个顺序API,旨在使lwip协议栈更易于使用(与事件驱动的原始 API 相比),同时仍保留零拷贝功能。
  要使用netconnAPI,需要一个操作系统,因为这个API需要使用线程。协议栈核心中的所有数据包处理(输入和输出)都是在一个专用线程内完成的-Tcpip线程)。应用程序线程使用邮箱和信号量与此专用线程通信。

二、netconn API

/*
创建netconn
t:netconn的类型,可取
  NETCONN_TCP       
  NETCONN_UDP       
  NETCONN_UDPLITE  
  NETCONN_UDPNOCHKSUM
  NETCONN_RAW 
返回:netconn句柄
*/
#define netconn_new(t)                  netconn_new_with_proto_and_callback(t, 0, NULL)
struct netconn* netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)

/*
删除netconn
conn:netconn句柄
*/
err_t   netconn_delete(struct netconn *conn);
/*
获得netconn的ip和端口
conn:netconn句柄
addr:保存获取的ip
port:保存获取的端口
local:为1时获取本地地址、为1时获取远端地址
*/
err_t   netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local);

/*
绑定本地ip地址到netconn
conn:netconn句柄
addr:本地ip
port:本地端口
*/
err_t   netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port);
/*
连接到远端ip和端口
conn:客户端本地ip
port:客户端本地端口
*/
err_t   netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port);
/*
仅可用于UDP,断开连接
conn:netconn句柄
*/
err_t   netconn_disconnect (struct netconn *conn);

/*
将tcp的连接切换成listen模式
conn:netconn句柄
*/
#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
/*
tcp服务器获取新建立的连接,也就是监听到的连接
conn:旧的连接
new_conn:新的连接
*/
err_t   netconn_accept(struct netconn *conn, struct netconn **new_conn)

/*
接收数据
conn:连接
new_buf:数据包结构体
*/
err_t   netconn_recv(struct netconn *conn, struct netbuf **new_buf);
/*
tcp发送数据
conn:连接
dataptr:发送缓冲区
size:发送大小
apiflag:标志
*/
#define netconn_write(conn, dataptr, size, apiflags) \
          netconn_write_partly(conn, dataptr, size, apiflags, NULL)
/*
关闭tcp连接
conn:连接
*/
err_t   netconn_close(struct netconn *conn);

/*
udp发送数据
conn:连接
buf:数据包结构体
*/
err_t   netconn_send(struct netconn *conn, struct netbuf *buf);

三、netconn示例:编写TCP服务器

#include "my_netconn.h"
#include "lwip/opt.h"
#include "usart.h"

#if LWIP_NETCONN
#include "lwip/sys.h"
#include "lwip/api.h"

#define TCPECHO_THREAD_PRIO  (osPriorityAboveNormal)

static void mytcp_thread(void *arg)
{
    
    
   struct netconn *conn, *newconn;
   err_t err;
   
   u8_t  tx_buf[20];//发送缓冲区
   u16_t rx_len=0;
   u8_t *temp = "cnt:%d\r\n";
   u16_t cnt =0;//要通过TCP显示的计数值
  
   LWIP_UNUSED_ARG(arg);

   /* Create a new connection identifier. */
   /* Bind connection to well known port number 7. */
   conn = netconn_new(NETCONN_TCP);
   netconn_bind(conn, IP_ADDR_ANY, 7);

   LWIP_ERROR("my tcpdemo: invalid conn", (conn != NULL), return;);

   /* Tell connection to go into listening mode. */
   netconn_listen(conn);
   /* Grab new connection. */
   err = netconn_accept(conn, &newconn);
   printf("accepted new connection %p\n", newconn);
   /* Process the new connection. */
   if (err == ERR_OK) 
   {
    
    
     while (1) 
     {
    
    
	  sprintf(tx_buf,temp,cnt);
	  tx_len = strlen((const char *)tx_buf);
	  cnt++;
	  err = netconn_write(newconn, tx_buf, tx_len, NETCONN_COPY);
	  vTaskDelay(1000);
     }
   }
}
//创建tcp线程
void mytcp_init(void)
{
    
    
  sys_thread_new("tcpecho_thread", mytcp_thread, NULL, (configMINIMAL_STACK_SIZE*2), TCPECHO_THREAD_PRIO);
}
#endif /* LWIP_NETCONN */

四、测试

在这里插入图片描述

五、总结

使用netconn api首先使用netconn_new创建一个连接,接着可以对这个连接进行删除、查询ip和端口、绑定ip和端口、连接远端地址、监听、接收连接、接收数据、发送数据、关闭连接。非常简单的实现了TCP服务器。

Guess you like

Origin blog.csdn.net/weixin_43810563/article/details/118768793