OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9430|回复: 7

用lwip能否在程序中同时实现tcp客户端,tcp服务器及udp的功能?

[复制链接]

10

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2017-7-28
在线时间
109 小时
发表于 2018-5-8 12:48:53 | 显示全部楼层 |阅读模式
5金钱
用lwip能否在程序中同时实现tcp客户端,tcp服务器及udp的功能?有实现的请发一下源码,不能发源码的请说一下实现的方式方法,三种功能单独的都已经实现了,但是不知道怎么合并,自己试着合并了一下发现还是只能实现其中一种功能


最佳答案

查看完整内容[请看2#楼]

实现了,但是当作为tcp客户端时因为要主动向服务器发起连接,服务器端需要提前开启。或者加个定时器进行定时连接或者在下面的if(t=200)后的大括号中加上连接服务器的语句,这样服务器端随时开启板子都能连上了@正点原子 谢谢原子哥帮顶
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2017-7-28
在线时间
109 小时
 楼主| 发表于 2018-5-8 12:48:54 | 显示全部楼层
michael91 发表于 2018-5-9 10:12
[mw_shl_code=c,true]#include "sys.h"
#include "string.h"
#include "delay.h"

实现了,但是当作为tcp客户端时因为要主动向服务器发起连接,服务器端需要提前开启。或者加个定时器进行定时连接或者在下面的if(t=200)后的大括号中加上连接服务器的语句,这样服务器端随时开启板子都能连上了@正点原子       谢谢原子哥帮顶
回复

使用道具 举报

10

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2017-7-28
在线时间
109 小时
 楼主| 发表于 2018-5-8 12:50:12 | 显示全部楼层
请知道的不吝赐教,非常感谢
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-5-9 01:41:32 | 显示全部楼层
帮顶
回复

使用道具 举报

10

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2017-7-28
在线时间
109 小时
 楼主| 发表于 2018-5-9 10:12:37 | 显示全部楼层
[mw_shl_code=c,true]#include "sys.h"
#include "string.h"
#include "delay.h"
#include "usart.h"
#include "dma.h"
#include "led.h"
#include "key.h"
#include "lwip_comm.h"
#include "LAN8720.h"
#include "timer.h"
#include "sram.h"
#include "malloc.h"
#include "lwip/netif.h"
#include "lwip_comm.h"
#include "lwipopts.h"
#include "tcp_server_demo.h"
#include "tcp_client_demo.h"
#include "udp_demo.h"

int main(void)
{
        u8 speed;
       
        delay_init(168);               //延时初始化
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //中断分组配置
       
        MYDMA_Config(DMA2_Stream5,DMA_Channel_4,(u32)&USART1->DR,(u32)uart_recbuf,uart_recbufsize);
        uart_init(115200);           //串口波特率设置
        LED_Init();                          //LED初始化
       
        mymem_init(SRAMIN);                //初始化内部内存池
        mymem_init(SRAMCCM);        //初始化CCM内存池
       
        TIM3_Int_Init(999,839); //100khz的频率,计数1000为10ms
        while(lwip_comm_init()) //lwip初始化
        {
                printf("LWIP Init Falied!\r\n");
                delay_ms(1200);
                printf("Retrying...\r\n");   
        }
        printf("LWIP Init Success!\r\n");
#if LWIP_DHCP
        while((lwipdev.dhcpstatus!=2)&&(lwipdev.dhcpstatus!=0XFF))//等待DHCP获取成功/超时溢出
        {
                lwip_periodic_handle();
        }
#endif
       
        speed=LAN8720_Get_Speed();//得到网速
        if(speed&1<<1)printf("Ethernet Speed:100M\r\n");
        else printf("Ethernet Speed:10M\r\n");
        printf("PORT: 8089\r\n");

        delay_ms(500);                        //延时1s
        delay_ms(500);
       
        while(1)
        {        
                u8 i;
                u8 res=0;               
                u8 t=0;
                err_t err;  
               
                struct ip_addr locipaddr;
                struct ip_addr rmtipaddr;          //远端ip地址
                IP4_ADDR(&locipaddr,lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
                IP4_ADDR(&rmtipaddr,lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);
               
               
                struct udp_pcb *udppcb;          //
                struct tcp_pcb *tcppcbclient;          //定义一个TCP服务器控制块
                struct tcp_pcb *tcppcbserver;          //定义一个TCP服务器控制块
                struct tcp_pcb *tcppcbconn;          //定义一个TCP服务器控制块
               
                udppcb=udp_new();
                tcppcbclient=tcp_new();        //创建一个新的pcb
                tcppcbserver=tcp_new();        //创建一个新的pcb
       
#if  1
                if(udppcb)//创建成功
                {
                        err=udp_connect(udppcb,&rmtipaddr,UDP_DEMO_PORT);//UDP客户端连接到指定IP地址和端口号的服务器
                        if(err==ERR_OK)
                        {
                                err=udp_bind(udppcb,&locipaddr,UDP_DEMO_PORT);//绑定本地IP地址与端口号
                                if(err==ERR_OK)        //绑定完成
                                {
                                        udp_recv(udppcb,udp_demo_recv,NULL);//注册接收回调函数
                                        udp_demo_flag |= 1<<5;                        //标记已经连接上       
                                }else res=1;
                        }else res=1;               
                }else res=1;
#endif

#if  0
                if(tcppcbclient)                        //创建成功
                {                        tcp_connect(tcppcbclient,&rmtipaddr,REMOTE_PORT,tcp_client_connected);//连接到目的地址的指定端口上,当连接成功后回调tcp_client_connected()函数
                }else res=1;
#endif

#if  1
                if(tcppcbserver)                        //创建成功
                {
                        err=tcp_bind(tcppcbserver,&locipaddr,TCP_SERVER_PORT);        //将本地IP与指定的端口号绑定在一起,IP_ADDR_ANY为绑定本地所有的IP地址
                        if(err==ERR_OK)        //绑定完成
                        {
                                tcppcbconn=tcp_listen(tcppcbserver);                         //设置tcppcb进入监听状态
                                tcp_accept(tcppcbconn,tcp_server_accept);         //初始化LWIP的tcp_accept的回调函数
                        }else res=1;  
                }else res=1;
#endif
               
                while(res==0)
                {
                       
                        if(udp_demo_flag&1<<6)
                        {
                                for(i=0;i<=udptotal_len;i++)   
                                {
                                        USART_SendData(USART1, udp_demo_recvbuf);    //向串口2发送数据
                                        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
                                }
                                udptotal_len=0;
                                udp_demo_flag&=~(1<<6);//标记数据已经被处理了.
                        }                        
                       
                        if(tcp_client_flag&1<<6)//是否收到数据
                        {
                                for(i=0;i<=tcpclienttotal_len;i++)   
                                {
                                        USART_SendData(USART1,tcp_client_recvbuf);    //向串口2发送数据
                                        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
                                }
                                tcpclienttotal_len=0;
                                tcp_client_flag&=~(1<<6);//标记数据已经被处理了.
                        }
                                               
                        if(tcp_server_flag&1<<6)
                        {
                                for(i=0;i<=tcpservertotal_len;i++)   
                                {
                                        USART_SendData(USART1, tcp_server_recvbuf);    //向串口2发送数据
                                        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
                                }
                                tcpservertotal_len=0;//
                                tcp_server_flag&=~(1<<6);//标记数据已经被处理了.
                        }
                               
                        if(udp_demo_flag&1<<7)
                        {
                               
                                udp_demo_senddata(udppcb);
                                udp_demo_flag&=~(1<<7);                          //清除数据发送标志位
                        }
                       
                        lwip_periodic_handle();
                        delay_ms(2);
                        t++;
                        if(t==200)
                        {
                                t=0;
                                LED0=!LED0;
                        }
                }
               
                udp_demo_connection_close(udppcb); //断开udp连接
                tcp_client_connection_close(tcppcbclient,0);//关闭TCP Client连接
                tcp_server_connection_close(tcppcbserver,0);//关闭TCP Server连接
                tcp_server_connection_close(tcppcbconn,0);//关闭TCP Server连接
                tcp_server_remove_timewait();
                memset(tcppcbserver,0,sizeof(struct tcp_pcb));
                memset(tcppcbconn,0,sizeof(struct tcp_pcb));        

       
                delay_ms(100);
        }
}

[/mw_shl_code]
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-5-10 01:53:28 | 显示全部楼层
michael91 发表于 2018-5-9 10:37
实现了,但是当作为tcp客户端时因为要主动向服务器发起连接,服务器端需要提前开启。或者加个定时器进行 ...

谢谢分享
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

13

主题

105

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
16874
金钱
16874
注册时间
2012-10-20
在线时间
48 小时
发表于 2018-5-16 14:32:15 | 显示全部楼层
你有试过,关闭所有控制块再重新打开吗?我测试了,单独开客户端或服务端,都可以关闭再重新打开,但是两个一起开,是可以正常运行,但是一关闭,再重新开,就不行了,无法再开了,程序进入超时里了,而且出现BUG,再里面四循环出不来了。
还有你有测试过大量数据传输吗?板子单独做客户端,电脑做服务器间隔20ms发送1K数据,程序也会死在协议栈里。
这个协议栈用了心不安
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2020-1-7
在线时间
26 小时
发表于 2021-1-8 16:11:23 | 显示全部楼层
michael91 发表于 2018-5-8 12:48
实现了,但是当作为tcp客户端时因为要主动向服务器发起连接,服务器端需要提前开启。或者加个定时器进行 ...

你好,可以共享下实现的例程吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 15:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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