STM32 LWIP(裸机) RAW接口通讯——TCP API讲解(含源码)

目录

LWIP移植:

TCP裸机编程:

  参考(官网API讲解链接):

TCP客户端连接 RAW API:

 TCP客户端发起连接源码:

TCP客户端数据发送/接收函数 RAW API:

 TCP客户端数据发送/接收源码:

关闭连接函数

遇到的问题


LWIP移植:

手动移植LWIP(裸机):
STM32H563 HAL库 LWIP裸机移植 (包含源代码 一文搞定 )_lwip 裸机-CSDN博客https://blog.csdn.net/weixin_67846820/article/details/137764818?spm=1001.2014.3001.5502基于CubeMX移植LWIP(裸机):

STM32F429及STM32H563 基于CubeMX HAL库LWIP裸机移植(超详细)_stm32cubemx lwip-CSDN博客https://blog.csdn.net/weixin_67846820/article/details/139880496?spm=1001.2014.3001.5502

TCP裸机编程:

使用lwip协议栈中的TCP通讯时,大部分都是需要回调函数。

注册回调函数后,协议栈会在适当时机自动调用该函数。

  参考(官网API讲解链接):

lwIP: Overview

下面是注册回调函数的接口:

TCP客户端连接 RAW API:

建立TCP控制块
API: struct tcp_pcb *tcp_new(void);
作    用: 建立新的TCP控制块
参    数:
返回值:

pcb:成功建立了新的TCP控制块

NULL:建立控制块失败

指定远程主机连接
API:

err_ttcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,

                            tcp_connected_fn connected);

作    用: 主动向指定远程主机发送连接
参    数:

pcb: 指定一个TCP控制块连接

ipaddr: 指定连接远程主机的IP

port:指定连接远程主机的端口

connected:指定连接后调用的回调函数

返回值:

ERR_OK:连接成功

其他:连接失败

指定处理错误的回调函数
API: void tcp_err(struct tcp_pcb *pcb, tcp_err_fn err);
作    用: 指定处理错误后调用的回调函数
参    数:

pcb: 指定需要处理错误的TCP控制块

err:指定错误发生时调用的回调函数

返回值:

 TCP客户端发起连接源码:

client_connected: 连接成功的回调函数

client_err:             连接异常的回调函数

#define	 	DEST_IP_ADDR0 		***		//对方IP
#define 	DEST_IP_ADDR1 		***  
#define 	DEST_IP_ADDR2		***   
#define 	DEST_IP_ADDR3		***
#define 	TCP_CLIENT_PORT 	***	    //端口号

//TCP初始化
void TCP_Client_Init(void)
{  
	ip4_addr_t server_ip;    //存放服务器IP 
	client_pcb = tcp_new();    //建立TCP控制块

	IP4_ADDR(&server_ip, DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);//合并IP地址
	
	//开始连接
	tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected);
	ip_set_option(client_pcb, SOF_KEEPALIVE);	


	//注册异常处理
	tcp_err(client_pcb, client_err);
}

//连接成功回调函数
static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
  return ERR_OK;
}

//连接错误回调函数
static void client_err(void *arg, err_t err)       
{
	//连接失败的时候释放TCP控制块的内存
	//printf("closeconnect release\n");
	//tcp_close(client_pcb);     //关闭连接函数 在下方了解
    //tcp_abort(client_pcb);
}

TCP客户端数据发送/接收函数 RAW API:

将TCP数据写入缓冲区
API: err_t tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags);
作    用: 将TCP数据写入缓冲区
参    数:

pcb: 指定所要发送数据的TCP控制块

dataptr:准备发送的数据

len: 数据长度

copy:参数为TCP_WRITE_FLAG_COPY(1)时,数据将被分配到属于堆栈的内存中

           参数为TCP_WRITE_FLAG_MORE(0)时,表示还有后续数据,这个标志表明可以延迟发送(适合发送大量分段数据时使用)。    

返回值:

ERR_OK:数据成功写入缓冲区

其他:写入失败

发送数据成功后,指定调用回调函数
API: void tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent);
作    用: 指定远程主机成功接收到数据后(发送数据成功后),调用的回调函数。
参    数:

pcb: 指定与远程主机相连接的TCP控制块

sent:指定远程主机成功接收到数据后(发送数据成功后),调用的回调函数

返回值:

ERR_OK:数据成功写入缓冲区

其他:写入失败

尝试将数据缓冲区数据发送出去
API:

err_t tcp_output(struct tcp_pcb *pcb);

作    用: tcp_write() 只是将数据放入缓冲区,写入缓冲区后可以尝试使用tcp_output函数将缓冲区数据发送出去,但何时发送还是根据TCP底层逻辑。
参    数:

pcb: 指定需要发送数据的TCP控制块

返回值:

ERR_OK:数据成功发送

其他:发送失败

有新的数据接收到时调用的回调函数
API: void tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv);
作    用: 指定当有新的数据接收到时调用的回调函数
参    数:

pcb: 指定所要接收数据的TCP控制块

recv:指定当新的数据接收到时调用的回调函数。

返回值:

用于获取接收到的数据的长度
API: void tcp_recved(struct tcp_pcb *pcb, u16_t len);
作    用: 当接收到数据时该函数必须被调用,用于获取接收到的数据的长度
参    数:

pcb: 指定所要接收数据的TCP控制块

len:获取接收到的数据的长度

返回值:

 TCP客户端数据发送/接收源码:

连接成功回调函数后,注册接收回调函数。

//连接成功回调函数
static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
	
	//注册一个接收回调函数
	tcp_recv(pcb,client_recv);
	
  return ERR_OK;
}
//接受数据函数
static err_t client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
	if (p != NULL) 
	{ 
		//接收数据长度
		tcp_recved(tpcb, p->tot_len);
        
        //注册发送成功回调函数
        tcp_sent(pcb, send_succeed_callback); 
        //返回接受到的数据
		tcp_write(tpcb, p->payload, p->tot_len, TCP_WRITE_FLAG_COPY);
        tcp_output(pcb);
    }
	return ERR_OK;
}

err_t send_succeed_callback(void *arg, struct tcp_pcb *tpcb,u16_t len)
{
    //数据发送完成后的处理
	return ERR_OK;
}

关闭连接函数

API: err_t tcp_close(struct tcp_pcb *pcb);
作    用: 关闭一个指定的TCP连接,调用后会释放指定的tcp控制块
参    数:

pcb: 指定所要关闭连接的TCP控制块

返回值:

ERR_OK:连接正常关闭。

其他:连接关闭失败

API: void tcp_abort(struct tcp_pcb *pcb);
作    用: 通过向远程主机发送RST(重置)段终止连接。pcb板被回收。这个函数永远不会失败。
参    数:

pcb: 指定所要关闭连接的TCP控制块

返回值:

遇到的问题

在使用TCP单次发送大量数据时发送不出去。

猜测是发送缓冲区满导致的,包括使用循环发送也是发送不出去。可以使用发送成功回调函数发送,当前数据发送完成后再次发送下一个组数据。

如果有问题或有更到的办法,欢迎探讨。

作者:梦途笑匠

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 LWIP(裸机) RAW接口通讯——TCP API讲解(含源码)

发表回复