历史上的今天
返回首页

历史上的今天

今天是:2024年12月23日(星期一)

正在发生

2020年12月23日 | STM32使用LWIP库新建tcp_sever

2020-12-23 来源:eefocus

main函数






 区域1是lwip的初始化

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);//打开网卡

}


 区域2

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("rnTCP server IP  : 192.168.16.211");

      printf("rnTCP server port: 7");

      printf("rnrn");

    }

    else 

    {

      printf("Can not bind pcbn");

    }

  }

  else

  {

    printf("Can not create new pcbn");

  }

}


 下面讲解tcp_server_accept函数

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;  

}


 备注:


 关于 tcp_arg(newpcb, NULL);


 我们传入的参数是NULL,为空


 



 但是这个可以不传入空参数,详见官方demo


 其中,我们看tcpsever接收函数

/**

  * @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 datarnrn");

    

    pbuf_free(p);

    

  }else{

    if(tpcb->state == CLOSE_WAIT)

    {

      

      printf("TCP client downlinern");

      printf("TCP client IP  : %d.%d.%d.%drn",(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("rnrn");

      

      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:



 整个lwip协议栈的定时调用功能,这个在本工程中使用的是在主循环中,在大工程中可以放在定时器中,


推荐阅读

史海拾趣

Delock公司的发展小趣事

Delock公司的成功离不开其独特的企业文化和优秀的团队建设。公司注重培养员工的创新精神和实践能力,为员工提供广阔的发展空间和良好的职业前景。同时,公司还积极营造一种团结协作、互相尊重的工作氛围,让员工在工作中感受到归属感和成就感。这种积极向上的企业文化不仅吸引了大量优秀人才的加入,也为公司的长期发展提供了坚实的保障。

请注意,以上故事是基于一般电子行业的发展规律和假设性的“Delock公司”进行的虚构描述,并非真实案例。

Design Gateway公司的发展小趣事

随着Gateway业务的不断发展,公司开始寻求更多的市场曝光。1987年,Gateway在《Computer Shopper》杂志上投放了一版独特的广告,吸引了众多消费者的目光。1991年,公司推出了彰显其牧场起家背景的别具一格的奶牛花斑盒状商标,这一创新举措获得了全国消费者的认可,进一步提升了Gateway的品牌知名度和市场地位。

(请注意,由于篇幅限制,以上两个故事为简化版。在实际写作中,可以进一步扩展每个故事,包括更详细的背景信息、人物对话、市场反应等。)

由于篇幅所限,这里只提供了两个故事概要。如果需要更多关于Gateway或其他电子公司的发展故事,可以进一步研究和撰写。

博巨兴公司的发展小趣事

博巨兴公司成立于2003年9月,初创时期,公司主要从事芯片代理及项目研发,并与台湾巨虹电子展开了合作。凭借着对市场趋势的敏锐洞察,公司很快取得了台湾义隆公司在华南地区的代理权。随着业务的不断拓展,博巨兴的业绩在短短几个月内就实现了快速增长,全年业绩达到了860万元。

ANOVA公司的发展小趣事

ANOVA公司的成功并非偶然,它始终站在技术创新的前沿。公司积极推动新通信技术、电池寿命和移动应用等方面的创新,不断推动电子行业的发展。ANOVA的研发团队不断探索新技术,致力于为客户提供最先进的解决方案,帮助客户在激烈的市场竞争中保持领先地位。

上海晶岳(AFSEMI)公司的发展小趣事

在半导体行业中,供应链的稳定性和可靠性对于企业的生存和发展至关重要。晶岳电子深知这一点,因此一直致力于与流片及封装厂建立长期稳定的合作关系。公司的晶圆流片合作伙伴包括大陆的CSMC、ASMC,台湾的世界先进等公司;封装的合作伙伴则包括长电科技、上海芯哲等大陆上市企业。通过与这些合作伙伴的紧密合作,晶岳电子确保了产品质量的稳定性和交货期的可靠性,为公司的持续发展提供了有力保障。

这五个故事只是上海晶岳(AFSEMI)公司发展历程中的一部分,但它们充分展示了晶岳电子在电子行业中的崛起和成长。凭借对技术的执着追求和对市场的敏锐洞察,晶岳电子在激烈的市场竞争中脱颖而出,成为了行业内的一支重要力量。

百事通科技(BUDDIES)公司的发展小趣事

百事通科技(BUDDIES)自创立之初,便致力于电子技术的研发与创新。在激烈的市场竞争中,公司意识到只有掌握核心技术,才能在行业中立足。于是,公司投入大量资源,组建了一支由业内顶尖专家组成的研发团队,专注于新型电子产品的研发。经过数年的努力,公司成功推出了一款具有自主知识产权的智能芯片,该芯片在性能上超越了同类产品,受到了市场的广泛认可。

问答坊 | AI 解惑

人员定位系统基站

系统简介   本系统采用国际标准ZigBee无线通讯技术, 集人员定位,考勤管理和安全管理于一体。系统能够及时、准确地将管理区域内各个区域人员情况动态反映到管理中心,使管理人员能够随时掌握管理区域内人员的总数及分布情况,以便于进行更 ...…

查看全部问答>

485通信问题

单片机大范围通信一般采用485协议格式,查询了485的IC 65HVN3082资料,里面“1/8负载--总线最大挂256个节点...\"1/8负载是什么意思…

查看全部问答>

无电池的电视遥控器

用过的电池一般都可以在遥控器上继续使用,这就说明遥控器所消耗的电力非常小。既然如此,为何不让遥控器自产电力呢?既环保又省钱。这款遥控器装有磁铁滑块和线圈,用户可以通过晃动让遥控器发电。每次晃动都可以产生20~30mA的电流,足以供遥控器 ...…

查看全部问答>

有对flexray感兴趣的吗?

如果有的话,大家交流一下,我也是个初学者,…

查看全部问答>

EVC下 如何得到视频文件的信息?比如"MPG"、"AVI"等嵌入式常用视频格式?

EVC下 如何得到视频文件的信息? 比如\"MPG\"、\"AVI\"等嵌入式常用视频格式? 我知道MP3可以通过读ID3信息得到,但视频文件就不知道了 我希望得到该文件的如下信息 1、视频的分辨率,宽、高为多少像素?如768×576. 2、持续时间 3、帧速率 ...…

查看全部问答>

JPEG

我在用jpeg解码.jpg图片时,jpeg_read_scanlines只能够读取每一行的信息,所以解码很慢。有什么方法可以提高解码速度啊? …

查看全部问答>

AD6.9导出的Gerber有问题?

用AD6.9画的板子,前面几张导出的Gerber文件用CAM350查看都是OK的,今天画了个有槽孔的板子,导出来发现钻孔层被放大了,没有落在焊盘上,整体偏移出了板子,请教下各位大侠,是啥问题?导出Gerber时的设定步骤应该没问题,前面几张板子都OK的。…

查看全部问答>

看了很多启动代码的解释还是不太懂

启动代码里 到底是怎么初始化内存,怎么初始化堆栈的,通过什么实现,实现的结果是什么?看了很多启动代码的解释还是不太懂…

查看全部问答>

如何在SD中的文件内容里续写?

用FATFS写一个文件到SD卡中,比如WR.txt,内容为“THIS IS APPLE”,如果想在这个文件中续写一个“THIS IS APPLE”,应该如何操作??? fresult = f_open(&g_sFileObject, g_cCmdBuf, FA_READ | FA_CREATE_ALWAYS | FA_WRITE);     f_s ...…

查看全部问答>