UIP的数据处理都在 “nwk_appcall”这个函数里面做数据发送也必须在这个函数里完成。下面是关于这个函数的宏定义“nwk_appcall”这个函数名称时自己定的,里面的处理代码也是自己写的。
#ifndef UIP_APPCALL
#define UIP_APPCALL nwk_appcall
#endif
这个函数是在协议栈接收到某个连接的数据,然后才会去调用这个函数。
如果UIP要主动发送数据呢,这时问题就出现了。
我通过研究发现其实要主动发送数据也是可以的,会比较麻烦,如果你的应用中必须要用的服务端主动向客户端发送数据这算曲线救国吧或者用其他的协议栈。
我的方法有两种:一种是主动调用
一种是通过 在UIP主任务中的 定时轮询数据时把数据发送出去
else if(timer_expired(&periodic_timer))
{
timer_reset(&periodic_timer);
for(int i = 0; i < UIP_CONNS; i++)
{
uip_periodic(i);
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0) {
uip_arp_out();
prvENET_Send();
}
}
}
在调用uip_periodic(i); 这个函数时会进入到UIP_APPCALL中去处理,uip_poll()为真,所有会发送数据。
在UIP_APPCALL 中发送数据
if(uip_poll())
{
uip_send (sendBuf, buffer_len); // 发送返回数据
}
这样发送数据的话不会马上发送出去会等待periodic_timer的时间到。
另一种是第一种的升级版,通过主动调用uip_poll_conn()发送数据
调用uip_poll_conn()会去执行UIP_APPCALL中的uip_poll的代码,然后主动发送数据。我这边把需要发送的数据的缓存放在连接结构体里面了所有有了以下的代码。
for( int i = 0; i < UIP_CONNS; i++ )
{
if(uip_conns[i].connect.send_buffer_len > 0) // 有数据需要发送的时候主动轮询
{
uip_poll_conn(&uip_conns[i]);
if( uip_len > 0 )
{
uip_arp_out();
prvENET_Send();
}
}
}