uip主动发数据

2019-08-14 20:06发布

目前正在做个网络相关的项目,用的uip。现在遇到个问题,当产生数据时不知道怎样直接将数据发送到网络上
目前知道一种方法是利用uip的轮询,当定时器超时时可以向网络上发数据。但是我需要一有数据立马发送,怎样才能做到?
各位大大有懂uip的吗?可否指点一二。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
正点原子
1楼-- · 2019-08-15 01:34
我们的例程,就可以主动发送数据啊:
[mw_shl_code=c,true]int main(void) { u8 key; u8 tcnt=0; u8 tcp_server_tsta=0XFF; u8 tcp_client_tsta=0XFF; uip_ipaddr_t ipaddr; Stm32_Clock_Init(9); //系统时钟设置 uart_init(72,9600); //串口初始化为9600 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 LCD_Init(); //初始化LCD KEY_Init(); //初始化按键 RTC_Init(); //初始化RTC Adc_Init(); //初始化ADC usmart_dev.init(72); //初始化USMART POINT_COLOR=RED; //设置为红 {MOD} LCD_ShowString(60,10,200,16,16,"WarShip STM32"); LCD_ShowString(60,30,200,16,16,"ENC28J60 TEST"); LCD_ShowString(60,50,200,16,16,"ATOM@ALIENTEK"); while(tapdev_init()) //初始化ENC28J60错误 { LCD_ShowString(60,70,200,16,16,"ENC28J60 Init Error!"); delay_ms(200); LCD_Fill(60,70,240,86,WHITE);//清除之前显示 }; uip_init(); //uIP初始化 LCD_ShowString(60,70,200,16,16,"KEY0:Server Send Msg"); LCD_ShowString(60,90,200,16,16,"KEY2:Client Send Msg"); LCD_ShowString(60,110,200,16,16,"IP:192.168.1.16"); LCD_ShowString(60,130,200,16,16,"MASK:255.255.255.0"); LCD_ShowString(60,150,200,16,16,"GATEWAY:192.168.1.1"); LCD_ShowString(30,200,200,16,16,"TCP RX:"); LCD_ShowString(30,220,200,16,16,"TCP TX:"); LCD_ShowString(30,270,200,16,16,"TCP RX:"); LCD_ShowString(30,290,200,16,16,"TCP TX:"); POINT_COLOR=BLUE; uip_ipaddr(ipaddr, 192,168,1,16); //设置本地设置IP地址 uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, 192,168,1,1); //设置网关IP地址(其实就是你路由器的IP地址) uip_setdraddr(ipaddr); uip_ipaddr(ipaddr, 255,255,255,0); //设置网络掩码 uip_setnetmask(ipaddr); uip_listen(HTONS(1200)); //监听1200端口,用于TCP Server uip_listen(HTONS(80)); //监听80端口,用于Web Server tcp_client_reconnect(); //尝试连接到TCP Server端,用于TCP Client while (1) { uip_polling(); //处理uip事件,必须插入到用户程序的循环体中 key=KEY_Scan(0); if(tcp_server_tsta!=tcp_server_sta)//TCP Server状态改变 { if(tcp_server_sta&(1<<7))LCD_ShowString(30,180,200,16,16,"TCP Server Connected "); else LCD_ShowString(30,180,200,16,16,"TCP Server Disconnected"); if(tcp_server_sta&(1<<6)) //收到新数据 { LCD_Fill(86,200,240,216,WHITE); //清除之前显示 LCD_ShowString(86,200,154,16,16,tcp_server_databuf); printf("TCP Server RX:%s ",tcp_server_databuf);//打印数据 tcp_server_sta&=~(1<<6); //标记数据已经被处理 } tcp_server_tsta=tcp_server_sta; } if(key==KEY_RIGHT)//TCP Server 请求发送数据 { if(tcp_server_sta&(1<<7)) //连接还存在 { sprintf((char*)tcp_server_databuf,"TCP Server OK %d ",tcnt); LCD_Fill(86,220,240,236,WHITE); //清除之前显示 LCD_ShowString(86,220,154,16,16,tcp_server_databuf);//显示当前发送数据 tcp_server_sta|=1<<5;//标记有数据需要发送 tcnt++; } } if(tcp_client_tsta!=tcp_client_sta)//TCP Client状态改变 { if(tcp_client_sta&(1<<7))LCD_ShowString(30,250,200,16,16,"TCP Client Connected "); else LCD_ShowString(30,250,200,16,16,"TCP Client Disconnected"); if(tcp_client_sta&(1<<6)) //收到新数据 { LCD_Fill(86,270,240,286,WHITE); //清除之前显示 LCD_ShowString(86,270,154,16,16,tcp_client_databuf); printf("TCP Client RX:%s ",tcp_client_databuf);//打印数据 tcp_client_sta&=~(1<<6); //标记数据已经被处理 } tcp_client_tsta=tcp_client_sta; } if(key==KEY_LEFT)//TCP Client 请求发送数据 { if(tcp_client_sta&(1<<7)) //连接还存在 { sprintf((char*)tcp_client_databuf,"TCP Client OK %d ",tcnt); LCD_Fill(86,290,240,306,WHITE); //清除之前显示 LCD_ShowString(86,290,154,16,16,tcp_client_databuf);//显示当前发送数据 tcp_client_sta|=1<<5;//标记有数据需要发送 tcnt++; } } delay_ms(1); } } //uip事件处理函数 //必须将该函数插入用户主循环,循环调用. void uip_polling(void) { u8 i; static struct timer periodic_timer, arp_timer; static u8 timer_ok=0; if(timer_ok==0)//仅初始化一次 { timer_ok = 1; timer_set(&periodic_timer,CLOCK_SECOND/2); //创建1个0.5秒的定时器 timer_set(&arp_timer,CLOCK_SECOND*10); //创建1个10秒的定时器 } uip_len=tapdev_read(); //从网络设备读取一个IP包,得到数据长度.uip_len在uip.c中定义 if(uip_len>0) //有数据 { //处理IP数据包(只有校验通过的IP包才会被接收) if(BUF->type == htons(UIP_ETHTYPE_IP))//是否是IP包? { uip_arp_ipin(); //去除以太网头结构,更新ARP表 uip_input(); //IP包处理 //当上面的函数执行后,如果需要发送数据,则全局变量 uip_len > 0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len>0)//需要回应数据 { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } }else if (BUF->type==htons(UIP_ETHTYPE_ARP))//处理arp报文,是否是ARP请求包? { uip_arp_arpin(); //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len(这是2个全局变量) if(uip_len>0)tapdev_send();//需要发送数据,则通过tapdev_send发送 } }else if(timer_expired(&periodic_timer)) //0.5秒定时器超时 { timer_reset(&periodic_timer); //复位0.5秒定时器 //轮流处理每个TCP连接, UIP_CONNS缺省是40个 for(i=0;i<UIP_CONNS;i++) { uip_periodic(i); //处理TCP通信事件 //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len>0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } } #if UIP_UDP //UIP_UDP //轮流处理每个UDP连接, UIP_UDP_CONNS缺省是10个 for(i=0;i<UIP_UDP_CONNS;i++) { uip_udp_periodic(i); //处理UDP通信事件 //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len > 0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } } #endif //每隔10秒调用1次ARP定时器函数 用于定期ARP处理,ARP表10秒更新一次,旧的条目会被抛弃 if(timer_expired(&arp_timer)) { timer_reset(&arp_timer); uip_arp_timer(); } } }[/mw_shl_code]
正点原子
2楼-- · 2019-08-15 06:03
 精彩回答 2  元偷偷看……
玄心空月
3楼-- · 2019-08-15 11:04
回复【3楼】正点原子:
---------------------------------
原子哥,uip_polling这个函数的定时器超时发送我试过了,但是项目需要有数据了就发出去,而不经过uip中timer的定时器超时,能不能做到?
玄心空月
4楼-- · 2019-08-15 12:37
回复【3楼】正点原子:
---------------------------------
谢谢原子哥,我懂了。按键触发那个是不需要经过定时器超时的。
anshuping
5楼-- · 2019-08-15 14:19
我也遇到和楼主一样的问题,板子做服务器可以连上网络调试软件,板子作为客户端就连不上,初始化的时候添加了

               uip_ipaddr_t ipaddr;       
   
        timer_set(&periodic_timer, CLOCK_SECOND / 2);
        timer_set(&arp_timer, CLOCK_SECOND * 10);

        tapdev_init();
        uip_arp_init;
        uip_init();                                                                       
        uip_ipaddr(ipaddr, 192,168,1,16);       
        uip_sethostaddr(ipaddr);                                            
        uip_ipaddr(ipaddr, 192,168,1,1);        
        uip_setdraddr(ipaddr);                                                 
        uip_ipaddr(ipaddr, 255,255,255,0);       
        uip_setnetmask(ipaddr);
        uip_listen(HTONS(1200));
        uip_listen(HTONS(80));                               
               uip_ipaddr(&ipaddr,192,168,1,100);       
        uip_connect(&ipaddr,htons(1400));          
但是作为客户端连接不上服务器,请大神帮帮忙呗,我现在弄的都快崩溃了
   switch(uip_conn->lport)
        {
                case HTONS(80):                                   
                        //httpd_appcall();
                        break;
                case HTONS(1200):                               
                    tcp_test_appcall();
                        break;
        }
        switch(uip_conn->rport)       
        {
            case HTONS(1400):
                         tcp_client_demo_appcall();
               break;
            default:
               break;
        }
这个也添加了,但是就是连接不上服务器          
Akatsuki_lim
6楼-- · 2019-08-15 16:36
如果时间充足的话,可以先跳去学习一下lwip,把原子的视频教程过一遍,然后再回来看uip,就会发现uip很多东西都不难理解

一周热门 更多>