使用lwIP的TCP/IP协议栈提供的服务有两种方式:一种是使用lwIP API接口,另一种是直接调用TCP和UDP模块中的函数。本文主要介绍第二种中TCP模块部分的主要函数。
本文在xilinx的SDK工具中根据生成的源码总结出的几个主要函数,源码中其它大部分函数均是被这几个主要函数的调用来实现功能的。通过这几个函数可以直接在裸机下运行实现协议。需要注意的是,所有函数均是基于“tcp_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协议控制块为连接监听状态,即作为主机角 {MOD}来等待客户端申请连接。
参数: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))
说明:作为一个客户端的角 {MOD}来连接一个主机,连接成功后会调用参数中提供的“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表示发送成功或没有可发送的数据,其它表示出错。