ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[应用相关] (转)LwIP_TCPIP 常用函数详解

[复制链接]
280|7
 楼主 | 2018-6-14 09:51 | 显示全部楼层 |阅读模式
此PCB管理tcp协议,包括连接、数据包、收发等状态
一、tcp.c实现的函数:
1、err_t tcp_close(struct tcp_pcb *pcb) 说明:断开PCB中的连接,释放其占用资源,无论其正在监听或已经建立了连接。参数:pcb表示要关闭的协议控制块。
返回:ERR_OK表示连接已经被断开,其它表示pcb没有被断开,其资源没有被释放。
PCB(protocol control block)协议控制块,包括tcp和udp等多种,每种协议有自己的协议控制块,如tcp_pcb。另外,err开头的数据类型一般是int型,表示状态,一般不需理会。
2、err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)说明:设置某个协议控制块用于连接的本地ip地址和端口号。
参数:pcb协议控制块;ipaddr表示ip地址的结构体,用IP_ADDR_ANY设置默认本地ip地址;port表示16位端口号。
返回:ERR_USE表示端口号被占用,ERR_OK表示设置成功
ip_addr结构体中只有一个32位整数项:ipaddr->addr,ip地址应由高到低位依次填充该项。这个IP地址的结构体应该在使用本函数前事先定义好。 3、struct tcp_pcb *
tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) 说明:设置该TCP协议控制块为连接监听状态,即作为主机角色来等待客户端申请连接。 参数:pcb协议控制块;backlog最大连接数限制,8位无符号整数,最大为255。一般应用是我们用tcp_listen(pcb)宏来替换这个函数,这个宏将backlog自动设置为255。
3、 void  tcp_recved(strcut tcp_pcb *pcb, u16_t len) 说明:在应用程序处理接收的数据之前,应该先调用该函数来扩大tcp窗口长度。参数:pcb协议控制块;len应用程序总共读取的数据长度。
4、static u16_t   tcp_new_port(void) 说明:分配一个新的端口号,(不与已经使用的端口号重复) 返回:新端口号,16位无符号整数。
5、err_t  tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)) 说明:作为一个客户端的角色来连接一个主机,连接成功后会调用参数中提供的“connected”函数(自己编写的函数,用于处理连接后的工作)。
参数:pcb协议控制块;ipaddr远端主机ip地址;port远端主机端口号;connected需要被调用的函数地址(函数名),否则会出错。 返回:状态,ERR_VAL表示参数错误(ip地址错误),ERR_OK表示连接申请已经发出,其它表示连接申请不能发出。
6、void  tcp_setprio(struct tcp_pcb *pcb, u8_t prio) 说明:设置连接的优先级,直接修改pcb->prio项。 参数:pcb协议控制块,prio优先级
7、static void  tcp_kill_prio(u8_t prio)
说明:终止比prio优先级低或相等的其它有效的连接。
参数:prio最小优先级。
8、struct tcp_pcb *tcp_alloc(u8_t prio)
说明:创建一个新的TCP协议控制块,为其pcb分配新空间并自动填充。 参数:prio新pcb的优先级,可能会终止其它连接。 返回:新pcb指针,状态是CLOSED关闭的。
9、struct tcp_pcb *tcp_new(void)
说明:用于创建一个新TCP协议控制块。该pcb在用tcp_bind函数绑定前,并不放在TCP PCB链表中。
返回:状态是关闭的新pcb指针。
这个函数直接用中间优先级64(可设置)去调用tcp_alloc函数返回结果。
10、void  tcp_arg(struct tcp_pcb *pcb, void *arg)
说明:用于给tcp_recv函数(下一个讲)中指定的回调函数传递参数。 参数:所传递的参数(以指针的形式)。 这个函数直接修改pcb->callback_arg项。
11、void  tcp_recv(struct tcp_pcb *pcb, err_t (*recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))说明:用于指定当TCP连接接收到数据后所调用的函数。 参数:pcb协议控制块;recv所指定的函数地址(函数名) 这个函数直接修改pcb->recv项。
12、void  tcp_send(struct tcp_pcb *pcb,
err_t (*send)(void *arg, struct tcp_pcb *tpcb, u16_t len))
说明:用于指定当TCP连接成功的发送一个数据包到远端后所调用的函数。 参数:pcb协议控制块;send所指定的函数地址(函数名) 这个函数直接修改pcb->send项。
13、void tcp_err(struct tcp_pcb *pcb,void (*errf)(void *arg, err_t err))说明:用于指定当前连接发生崩溃性错误后所调用的函数。 参数:pcb协议控制块;errf所指定的函数地址(函数名) 这个函数直接修改pcb->errf项。
14、void  tcp_accept(struct tcp_pcb *pcb,
  err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)
说明:用于指定当前连接在监听状态时有其他端口与之连接成功后所调用的函数。
参数:pcb协议控制块;accept所指定的函数地址(函数名) 这个函数间接性的修改了pcb->accept项。
15、void  tcp_poll(struct tcp_tcb *pcb,
   err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval) 说明:用于指定TCP周期性的回调函数。
参数:pcb协议控制块;poll所指定的函数地址(函数名);interval粗糙的指定TCP周期间隔时间。
这个函数每秒钟被调用两次,直接修改pcb->poll和pollinterval这两项。
16、void  tcp_pcb_purge(struct tcp_pcb *pcb)
说明:用于清理TCP PCB。清空缓存数据并释放缓存资源。 参数:pcb被清理的协议控制块。 但是这个协议控制块本身还存在。
二、tcp_out.c实现的函数
1、err_t tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)说明:发送TCP数据包,但并不会立即发送。
参数:pcb协议控制块;data要发送的数据指针;len要啊发送的数据长度;apiiflags包括下面两种标识TCP_WRITE_FLAG_COPY表示数据会被复制到栈内缓存后再发送,TCP_WRITE_FLAG_MORE表示在最后的片段上置位PSH选项。 返回:ERR_OK表示发送成功,其它表示发送失败。
实际上这个函数仅是将数据放入发送队列中,但并不会立即发送,它会等待更多的数据一并发送,这样会更有效率。如果需要立即发送的话,这个函数用后要调用tcp_output函数(下一个讲)。
2、err_t tcp_output(struct tcp_pcb *pcb)
说明:从发送队列中查看有多少待发送的数据包,并将它们发送出去。 参数:pcb协议控制块
返回:ERR_OK表示发送成功或没有可发送的数据,其它表示出错。 3、void tcp_keepalive(struct tcp_pcb *pcb) 说明:保持链路处于live状态,尽管没有数据
4、err_t tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,             u8_t flags, u8_t apiflags, u8_t optflags) 说明:将TCP数据排序以发送
5、err_t  tcp_output(struct tcp_pcb *pcb) 说明:发送能够发送的数据
6、static void  tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) 说明:发送TCP分段
7、void  tcp_rexmit(struct tcp_pcb *pcb) 说明:将第一个没有ACK的数据段重传
8、void  tcp_rexmit_rto(struct tcp_pcb *pcb) 说明:重传所有没有ACK的数据段
9、void  tcp_rst(u32_t seqno, u32_t ackno,  struct ip_addr *local_ip, struct ip_addr *remote_ip,  u16_t local_port, u16_t remote_port) 说明:发送rst消息
10、err_t  tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags) 说明:发送没有数据的flag包
11、void   tcp_zero_window_probe(struct tcp_pcb *pcb)
说明:当对方的通告窗口为0时,持续定时器向对方发送一个探测报文,判断对方接收窗口是否已经打开

三、tcp_in.c实现函数
1、static err_t   tcp_listen_input(struct tcp_pcb_listen *pcb) 说明:当监听的接口需要的分段到达的动作,被tcp_input()调用
2、void   tcp_input(struct pbuf *p, struct netif *inp) 说明:TCP输入最初始的处理,包括头验证和分用
3、static void   tcp_parseopt(struct tcp_pcb *pcb) 说明:解析进入分段的参数
4、static err_t  tcp_process(struct tcp_pcb *pcb) 说明:实现TCP的状态机
5、static u8_t   tcp_receive(struct tcp_pcb *pcb)
说明:被tcp_process调用;首先检查是否是对Buff数据的ack,如是则释放空间;接着是接收数据
6、static err_t   tcp_timewait_input(struct tcp_pcb *pcb) 说明:被tcp_input调用,当处于TIME_WAIT状态的连接分段到达   

     lwIp的作者做了大量的工作以方便像我这种懒人移植该协议栈,基本上只需修改一个配置头文件和改写3个函数即可完成lwIP的移植。要改写的3个函数都位于网络的最底层,它取决于你使用的是何种网络接口芯片,比如非常常见的RTL8201Bl,最近很火的TI的lm3s6000/8000/9000系列片上集成的网络接口模块等等。之所以要改写,是因为勤劳的lwIP作者已经写出来这三个函数的基本雏形,再次感谢Adam。要改写的函数位于lwIP-1.3.0/src/netif/ethernetif.c中,你也可以用自己更合适的网络接口名来代替“ethernetif”。另外还有一个配置头文件,叫做lwipopts.h文件,它要放在工程目录下。这个文件来源于lwIP-1.3.0/src/include/lwip/opt.h头文件,是对整个协议栈的一个配置,比如是否使用TCP/UDP/DHCP协议等等。

    先来看看移植要注意的三个函数,第一个函数为ethernerif_init()函数,这个函数先是设置与协议栈有关的底层操作,指定底层接收回调函数等,接着对实际网络接口芯片进行初始化,设置硬件的工作方式,开放中断等。第二个函数为low_level_output函数,主要目的是将要发送的数据包分解成网络接口芯片能识别的书籍结构并将数据发送到链路上。第三个函数为low_level_input()函数,主要接收以太网数据并将数据打包成lwIP能识别的数据结构。     配置头文件lwipopts.h内容较多,按照具体应用进行配置。     最后要说的是lwip协议栈的cc.h文件,该文件中定义了与处理器相关的数据类型,要稍微注意一下。
    pbuf结构体位于src/include/lwip/pbuf.h中

    以太网中断收到的数据就先存放到这个结构体组成的数据链中,然后将它交付给上层协议.

| 2018-6-14 11:04 | 显示全部楼层
表示对TCP这块看不懂。
 楼主 | 2018-6-14 13:22 | 显示全部楼层
gaoke231 发表于 2018-6-14 11:04
表示对TCP这块看不懂。

没关系 先通讯上再一个个看
| 2018-6-14 14:15 | 显示全部楼层
木木guainv 发表于 2018-6-14 13:22
没关系 先通讯上再一个个看

厉害,期待,
| 2018-6-14 15:30 | 显示全部楼层
MARK,非常有用。
| 2018-6-14 20:28 | 显示全部楼层
真是太详细了  好资料啊
 楼主 | 2018-6-15 13:24 | 显示全部楼层
我自己在弄 所以一直关注这些
| 2018-6-19 14:25 | 显示全部楼层
楼主辛苦了感谢分享
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

快速回复 返回顶部 返回列表