欢迎查看本文所在的系列,STM32的LWIP应用,点击跳转
main函数
void LwIP_Init(void)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
mem_init();//内存堆初始化
memp_init();//内存池初始化
IP4_ADDR(&ipaddr, 192, 168, 16, 211);
IP4_ADDR(&netmask, 255, 255 , 255, 0);
IP4_ADDR(&gw, 192, 168, 16, 1);
netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);//添加新网卡到网卡列表
netif_set_default(&netif);//将网卡设置为默认网卡
netif_set_up(&netif);//打开网卡
}
void tcp_server_init(void)
{
/* create new tcp pcb */
tcp_server_pcb = tcp_new();//建立一个新的连接标志(pcb),在定义一个tcp_pcb控制块后应该首先被调用,以建立该控制块的连接标志
if (tcp_server_pcb != NULL)
{
err_t err;
/* bind echo_pcb to port 7 (ECHO protocol) */
err = tcp_bind(tcp_server_pcb, IP_ADDR_ANY, 7);//绑定本地的IP地址和端口号,可以将其绑定在一个任意的本地IP地址上,它也只能在函数tcp_new()调用之后才能调用
if (err == ERR_OK)
{
/* start tcp listening for echo_pcb */
tcp_server_pcb = tcp_listen(tcp_server_pcb);//在绑定成功后,监听端口,在这里监听端口,说明是建立的服务器,与之对应的是tcp_connect,代表的是客户机
/* initialize LwIP tcp_accept callback function */
tcp_accept(tcp_server_pcb, tcp_server_accept);//接收后调用此函数 ,回调函数,通知LwIP一个新来的连接已经被接收,这其中tcp_server_accept是函数名字,这或许也应该叫回调函数的注册
printf("Create TCP server success");
printf("\r\nTCP server IP : 192.168.16.211");
printf("\r\nTCP server port: 7");
printf("\r\n\r\n");
}
else
{
printf("Can not bind pcb\n");
}
}
else
{
printf("Can not create new pcb\n");
}
}
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
err_t ret_err;
/* set priority for the newly accepted tcp connection newpcb */
tcp_setprio(newpcb, TCP_PRIO_MIN);//设置这个网络控制块的优先级
/* pass newly allocated es structure as argument to newpcb */
tcp_arg(newpcb, NULL);//传递一个参数 arg 给后面的调用使用,可以传一个结构体,指定应该传递给所有回调函数的应用程序的具体状态,详见下面的备注
/* initialize lwip tcp_recv callback function for newpcb */
tcp_recv(newpcb, tcp_server_recv);//当服务器接收到数据时调用tcp_server_recv函数
/* initialize lwip tcp_err callback function for newpcb */
tcp_err(newpcb, tcp_server_error);//当服务器出现错误时调用tcp_server_error函数
/* initialize lwip tcp_poll callback function for newpcb */
tcp_poll(newpcb, tcp_server_poll, 10);//定时调用tcp_server_poll函数,参数10,代表每间隔5s调用,其它看上面区域3的解释
/* initialize lwip tcp_sever_sent_ok callback function for newpcb */
tcp_sent(newpcb, tcp_sever_sent_ok);//当服务器发送完数据之后调用tcp_sever_sent_ok函数
ret_err = ERR_OK;
return ret_err;
}
/**
* @brief This function is the implementation for tcp_recv LwIP callback
* @param arg: pointer on a argument for the tcp_pcb connection
* @param tpcb: pointer on the tcp_pcb connection
* @param pbuf: pointer on the received pbuf
* @param err: error information regarding the reveived pbuf
* @retval err_t: error code
*/
static err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
uint8 *p_data;
uint32 data_len;
if ((err == ERR_OK) && (p != NULL)){
tcp_server_send_back(tpcb, p);
printf("TCP server returns the received data\r\n\r\n");
pbuf_free(p);
}else{
if(tpcb->state == CLOSE_WAIT)
{
printf("TCP client downline\r\n");
printf("TCP client IP : %d.%d.%d.%d\r\n",(uint8)(tpcb->remote_ip.addr),
(uint8)((tpcb->remote_ip.addr)>>8),
(uint8)((tpcb->remote_ip.addr)>>16),
(uint8)((tpcb->remote_ip.addr)>>24));
printf("TCP client port: %d",tpcb->remote_port);
printf("\r\n\r\n");
tcp_arg(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_recv(tpcb, NULL);
tcp_err(tpcb, NULL);
tcp_poll(tpcb, NULL, 0);
/* close tcp connection */
tcp_close(tpcb);
}
}
return ERR_OK;
}
区域3:
如果看文字版太枯燥,可以点击看视频版:点击跳转