之前用过uip作为udp使用,但将它作为server还没有涉及到,最近有个小项目中需要使用。以下针对它作为tcp_server流程测试和探索。
void Uip_Appcall(void)
{
int len,i;
char *nptr;
//printf("uip_flags = %d\r\n",uip_flags);
//extern struct uip_conn uip_conns[UIP_CONNS];
switch(uip_flags)
{
case UIP_CONNECTED:{
printf("uip_server port:%d come to a new client connected (IP: %d.%d.%d.%d Port:%d)\r\n",HTONS(uip_conn->lport), \
uip_ipaddr1(uip_conn->ripaddr), \
uip_ipaddr2(uip_conn->ripaddr), \
uip_ipaddr3(uip_conn->ripaddr), \
uip_ipaddr4(uip_conn->ripaddr), \
HTONS(uip_conn->rport));
}break;
case UIP_CLOSE:{
printf("uip_server port:%d come to a new client closed (IP: %d.%d.%d.%d Port:%d)\r\n",HTONS(uip_conn->lport), \
uip_ipaddr1(uip_conn->ripaddr), \
uip_ipaddr2(uip_conn->ripaddr), \
uip_ipaddr3(uip_conn->ripaddr), \
uip_ipaddr4(uip_conn->ripaddr), \
HTONS(uip_conn->rport));
//测试被动关闭
}break;
case UIP_NEWDATA:{
len=uip_datalen();
nptr=(char*)uip_appdata;
if(len < UIP_SEND_BUF_MAX_LEN)
{
memcpy(uipSendBuf,nptr,len);
uip_send(uipSendBuf,len);
for(i = 0; i < len; i ++)
printf("%c",uipSendBuf[i]);
printf("\r\n");
}
else
printf("uip recv bytes over flow user cache!\r\n");
uip_close(); //测试主动关闭
}break;
case UIP_ACKDATA: //发送一包数据后,会执行到这里
case UIP_POLL:{ //空闲时,会执行到这里。
//当前连接可以发送数据 (注意:此处发送缓存后,缓存标志要作已发送。下一次不要作为发送缓存了,否则可能一直重发)
//因为uip空闲时,该处一直能轮询得到。
}break;
default:break;
}
}
void Udp_Appcall(void)
{
}
void uipTcp_Init(void)
{
uip_listen(HTONS(60000));
}
struct timer periodic_timer, arp_timer;
//struct uip_udp_conn myUdp_Con;
//struct uip_udp_conn *pMyUpd_Con;
//char mySendbuf[20]={"hello,eric!\r\n"};
u8 uipSendBuf[UIP_SEND_BUF_MAX_LEN];
void UserUip_Init(void)
{
struct uip_eth_addr eaddr={{0x00,0xbd,0x3b,0x33,0x05,0x71}};
uip_ipaddr_t ipaddr;
Queue_Init(ð_sRxQueue);
timer_set(&periodic_timer, CLOCK_SECOND / 2);
timer_set(&arp_timer, CLOCK_SECOND * 10);
tapdev_init((u8*)eaddr.addr);
uip_init();
uip_arp_init();
uip_ipaddr(ipaddr, 192,168,1,120); //配置Ip
uip_sethostaddr(ipaddr);
uip_ipaddr(ipaddr, 192,168,1,1); //配置网关
uip_setdraddr(ipaddr);
uip_ipaddr(ipaddr, 255,255,255,0); //配置子网掩码
uip_setnetmask(ipaddr);
uip_setethaddr(eaddr);
uipTcp_Init();
}
void UserUip_Task(void)
{
int i;
//atic u32 arptimer=0;
uip_len = tapdev_read(); //从网卡读取数据
if(uip_len > 0)
{ //如果数据存在则按协议处理
if(BUF->type == htons(UIP_ETHTYPE_IP))
{
//如果收到的是IP数据,调用uip_input()处理
uip_arp_ipin();
uip_input();
/* 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();
tapdev_send();
}
}
else if(BUF->type == htons(UIP_ETHTYPE_ARP))
{ //如果收到的是ARP数据,调用uip_arp_arpin处理
uip_arp_arpin();
/* 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)
{
tapdev_send();
}
}
}
else if(timer_expired(&periodic_timer))
{ //查看0.5s是否到了,调用uip_periodic处理TCP超时程序
timer_reset(&periodic_timer);
for(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();
tapdev_send();
}
}
#if UIP_UDP
for(i = 0; i < UIP_UDP_CONNS; i++)
{
uip_udp_periodic(i); //处理udp超时程序
/* 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();
tapdev_send();
}
}
#endif /* UIP_UDP */
/* Call the ARP timer function every 10 seconds. */ //10s到了就处理ARP
if(timer_expired(&arp_timer))
{
timer_reset(&arp_timer);
uip_arp_timer();
}
}
}
void Udp_Appcall(void)
{
}
void uipTcp_Init(void)
{
uip_listen(HTONS(60000));
}
void uip_log(char *msg)
{
printf("uIP log message: %s\n", msg);
}