打印

stm32 107以太网库的demo使用uip的问题,

[复制链接]
6153|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xixihaha0|  楼主 | 2010-10-11 17:02 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
官方的以太网uip的demo是一个webserver,我将webserver等内容去掉,准备弄过网络与串口互转的设备,先贴一下代码,再说明问题:
uipMain.c中的uipMain函数

void uIPMain(void)
{
  u8_t i, arptimer;
  uip_eth_hdr *BUF = (uip_eth_hdr*)uip_buf;//uip_buf是一个1502大小的数组,用于全局来处理以太网帧
  
  u32 size;
  /* Initialize the uIP TCP/IP stack. */
  uip_init();
  arptimer = 0;
  tcp_server_init();//此处将httpd_init改成了我的一个初始化函数
  
  while(1)
  {
      /* Let the tapdev network device driver read an entire IP packet
      into the uip_buf. If it must wait for more than 0.5 seconds, it
      will return with the return value 0. If so, we know that it is
      time to call upon the uip_periodic(). Otherwise, the tapdev has
      received an IP packet that is to be processed by uIP. */
      
      size = ETH_HandleRxPkt(uip_buf);//处理接收的包
      
      if (size > 0)
          uip_len = size;
      
      if(uip_len <= 0x0)//表明读取数据超时
      {
          for(i = 0; i < UIP_CONNS; i++)//tcp部分
          {
              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();
                  TransmitPacket();
              }
          }/* end for */
         
#if UIP_UDP
          for(i = 0; i < UIP_UDP_CONNS; i++)//udp部分
          {
              uip_udp_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();
                  TransmitPacket();
              }
          } /* end for */
#endif /* UIP_UDP */
         
          /* Call the ARP timer function every 10 seconds. */
          if(++arptimer == 20)
          {
              uip_arp_timer();
              arptimer = 0;
          }
      } /* end if(uip_len <= 0x0) */
      
      else
      {
          if(BUF->type == htons(UIP_ETHTYPE_IP))//如果是IP包
          {
              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();
                  TransmitPacket();
              }
          }
          else if(BUF->type == htons(UIP_ETHTYPE_ARP))//如果是ARP包
          {
              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)
              {
                  TransmitPacket();
              }
          }
      } /* end else */
  }
}


tcp_server.c
#include "uip.h"
#include "tcp_server.h"
#include <stdio.h>

#define HOST_IDLE 0 //主机空闲,一直处于监听状态
#define CLIENT_GET 1 //客户端连接上
#define DATA_SEND 2

struct tcp_server_state *tss;//tcp sever state

void tcp_server_init(void)
{
uip_listen(HTONS(1000));
}


/* 注意uip如果做为tcp服务器端向客户端发送数据只有三种方法
1.在收到新数据时进行发送
2.在需要重发时进行发送
3.在收到对方收到数据的ack确认后,如果有数据可以进行发送 */
void tcp_server_appcall(void)
{
tss = (struct tcp_server_state *)(uip_conn->appstate);

if(uip_connected()) //客户端接入
{
printf("Tcp Clinet In \r\n");
tss->state = CLIENT_GET;
return;
}

if(uip_newdata()|| uip_rexmit()) //收到新的数据
{
switch(tss->state)
{
case CLIENT_GET:
printf("Get The Clinet Data Num is %d\r\n",uip_datalen());
if(!uip_poll())
{
uip_send("ok\n", 3);
tss->state = DATA_SEND;
}
break;

default:break;
}
}

if(uip_acked() && tss->state == DATA_SEND)
{
tss->state = CLIENT_GET;
printf("send has been ack\r\n");
}

if(uip_poll())
{
//复制数据到缓冲区
return ;
}

if(uip_timedout())
{
printf("uip time out \r\n");
}

if(uip_aborted()) //是否客户端中断关闭
{
printf("The Client Is Aborted\r\n");
tss->state = HOST_IDLE;
}

if(uip_closed()) //是否客户端中断关闭
{
printf("The Client Is Closed\r\n");
tss->state = HOST_IDLE;
}
}


tcp_server.h
#ifndef _SERVER_H
#define _SERVER_H

#include "uipopt.h"

void tcp_server_init(void);
void tcp_server_appcall(void);

#ifndef UIP_APPCALL
#define UIP_APPCALL tcp_server_appcall
#endif

struct tcp_server_state {
u8_t state;
};

/* UIP_APPSTATE_SIZE: The size of the application-specific state
stored in the uip_conn structure. */
#ifndef UIP_APPSTATE_SIZE
#define UIP_APPSTATE_SIZE (sizeof(struct tcp_server_state))
#endif

#endif


现在问题是,我服务器端进行连接后,在第三次握手时,始终检测不到客户端的 ack包,而一直在发送syn ack包(二次握手用的包)?wrieshark抓图如下:

其中服务器端uip的ip设置为 192.168.0.102,客户端我的pc机 的ip设置为 192.168.1.101,是不是stm移植的uip有bug?请各位指导一下
沙发
xixihaha0|  楼主 | 2010-10-11 20:51 | 只看该作者
高手不见了?赶紧自己顶一下,要不沉了

使用特权

评论回复
板凳
taomo| | 2011-3-1 20:57 | 只看该作者
顶啊,很好啊,其实我还是没有懂啊,只要我还很菜啊

使用特权

评论回复
地板
fan_qh| | 2012-3-15 17:09 | 只看该作者
很好,定,能把工程分享一下就好了

使用特权

评论回复
5
zouzhuliu| | 2014-1-2 16:25 | 只看该作者
请问,你的size = ETH_HandleRxPkt(uip_buf)是取的DMA描述符列表吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

164

帖子

1

粉丝