官方的以太网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?请各位指导一下
|