Uip WebClient 实现的功能是接入互联网,通过http协议访问某个网站。HTTP是一种应用层协议。基于TCP/IP。 TCP/IP作为传输层协议解决数据如何在网络中传输,HTTP作为应用层协议,解决如何包装数据。默认的HTTP访问端口为80端口。
Uip + stm32 的移植参见
相关文件:
Apps/resolv.c 文件实现的是DNS,动态域名解析等。
Apps/webclient.c主要实现HTTP的协议的解析。
首先需要修改User/uip-con.h配置文件:
01
|
#define UIP_CONF_LOGGING 0 //logging off
|
03
|
//typedef int uip_tcp_appstate_t; //出错可注释
|
04
|
typedef int uip_udp_appstate_t; //出错可注释
|
07
|
/*#include "hello-world.h"*/
|
08
|
/*#include "telnetd.h"*/
|
09
|
/*#include "webserver.h"*/
|
10
|
/*#include "dhcpc.h"*/
|
11
|
/*#include "resolv.h"*/
|
12
|
#include "webclient.h" //包含WebClient 文件
|
14
|
#include "app_call.h" //加入一个Uip的数据接口文件
|
修改User/mainc 调用相关WebClient函数 配置DNS以及设定页面地址
01
|
#include "stm32f10x.h"
|
14
|
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
17
|
#define NULL (void *)0
|
20
|
static unsigned char mymac[6] = {0x04,0x02,0x35,0x00,0x00,0x01};
|
22
|
void RCC_Configuration(void);
|
23
|
void GPIO_Configuration(void);
|
24
|
void USART_Configuration(void);
|
30
|
struct timer periodic_timer, arp_timer;
|
34
|
USART_Configuration();
|
37
|
timer_set(&periodic_timer, CLOCK_SECOND / 2);
|
38
|
timer_set(&arp_timer, CLOCK_SECOND * 10);
|
40
|
SysTick_Config(72000);
|
001
|
uip_ipaddr(ipaddr, 192, 168, 1, 15); //配置Ip
|
002
|
uip_sethostaddr(ipaddr);
|
003
|
uip_ipaddr(ipaddr, 192, 168, 1, 1); //配置网关
|
004
|
uip_setdraddr(ipaddr);
|
005
|
uip_ipaddr(ipaddr, 255, 255, 255, 0); //配置子网掩码
|
006
|
uip_setnetmask(ipaddr);
|
010
|
uip_ipaddr(ipaddr, 8,8,8,8); //DNS server ,Google DNS Server
|
012
|
resolv_query("www.ichanging.org");
|
016
|
uip_len = tapdev_read(); //从网卡读取数据
|
020
|
if(BUF->type == htons(UIP_ETHTYPE_IP)) { //如果收到的是IP数据,调用uip_input()处理
|
025
|
/* If the above function invocation resulted in data that
|
026
|
should be sent out on the network, the global variable uip_len is set to a value > 0. */
|
034
|
}else if(BUF->type == htons(UIP_ETHTYPE_ARP)){ //如果收到的是ARP数据,调用uip_arp_arpin处理
|
038
|
/* If the above function invocation resulted in data that
|
039
|
should be sent out on the network, the global variable uip_len is set to a value > 0. */
|
047
|
}else if(timer_expired(&periodic_timer)){ //查看0.5s是否到了,调用uip_periodic处理TCP超时程序
|
049
|
timer_reset(&periodic_timer);
|
050
|
for(i = 0; i < UIP_CONNS; i++) {
|
054
|
/* If the above function invocation resulted in data that
|
055
|
should be sent out on the network, the global variable uip_len is set to a value > 0. */
|
064
|
for(i = 0; i < UIP_UDP_CONNS; i++)
|
067
|
uip_udp_periodic(i); //处理udp超时程序
|
069
|
/* If the above function invocation resulted in data that
|
070
|
should be sent out on the network, the global variable uip_len is set to a value > 0. */
|
079
|
/* Call the ARP timer function every 10 seconds. */ //10s到了就处理ARP
|
080
|
if(timer_expired(&arp_timer))
|
082
|
timer_reset(&arp_timer);
|
090
|
/*******************************WebClient Set***************************************/
|
092
|
void resolv_found(char *name, u16_t *ipaddr) //DNS 找到对应服务器IP
|
097
|
printf("Host '%s' not found.\n", name);
|
099
|
printf("Found name '%s' = %d.%d.%d.%d\n", name,
|
100
|
htons(ipaddr[0]) >> 8,
|
101
|
htons(ipaddr[0]) & 0xff,
|
102
|
htons(ipaddr[1]) >> 8,
|
103
|
htons(ipaddr[1]) & 0xff);
|
104
|
if(webclient_get("www.ichanging.org", 80, "/index.php"))
|
106
|
printf("the connection was initiated");
|
108
|
printf("the host name could not be found in the cache or TCP connection could not be created.");
|
113
|
void webclient_closed(void)
|
115
|
//printf("Webclient: connection closed\n");
|
117
|
void webclient_aborted(void)
|
119
|
//printf("Webclient: connection aborted\n");
|
121
|
void webclient_timedout(void)
|
123
|
//printf("Webclient: connection timed out\n");
|
125
|
void webclient_connected(void)
|
127
|
//printf("Webclient: connected, waiting for data...\n");
|
129
|
void webclient_datahandler(char *data, u16_t len)
|
131
|
//printf("Webclient: got %d bytes of data.\n", len);
|
135
|
/*******************************Stm32 Set***************************************/
|
137
|
void GPIO_Configuration(void)
|
139
|
GPIO_InitTypeDef GPIO_InitStructure;
|
140
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
142
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
143
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
144
|
GPIO_Init(GPIOA , &GPIO_InitStructure);
|
146
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
147
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
148
|
GPIO_Init(GPIOA , &GPIO_InitStructure);
|
153
|
void RCC_Configuration(void)
|
155
|
/* 定义枚举类型变量 HSEStartUpStatus */
|
156
|
ErrorStatus HSEStartUpStatus;
|
161
|
RCC_HSEConfig(RCC_HSE_ON);
|
163
|
HSEStartUpStatus = RCC_WaitForHSEStartUp();
|
164
|
/* 判断HSE起是否振成功,是则进入if()内部 */
|
165
|
if(HSEStartUpStatus == SUCCESS)
|
167
|
/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
|
168
|
RCC_HCLKConfig(RCC_SYSCLK_Div1);
|
169
|
/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
|
170
|
RCC_PCLK2Config(RCC_HCLK_Div1);
|
171
|
/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
|
172
|
RCC_PCLK1Config(RCC_HCLK_Div2);
|
174
|
FLASH_SetLatency(FLASH_Latency_2);
|
176
|
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
|
177
|
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
|
178
|
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
|
182
|
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
|
183
|
/* 选择SYSCLK时钟源为PLL */
|
184
|
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
|
185
|
/* 等待PLL成为SYSCLK时钟源 */
|
186
|
while(RCC_GetSYSCLKSource() != 0x08);
|
188
|
/* 打开APB2总线上的GPIOA时钟*/
|
189
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
|
193
|
void USART_Configuration(void)
|
195
|
USART_InitTypeDef USART_InitStructure;
|
196
|
USART_ClockInitTypeDef USART_ClockInitStructure;
|
198
|
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
|
199
|
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
|
200
|
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
|
201
|
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
|
202
|
USART_ClockInit(USART1 , &USART_ClockInitStructure);
|
204
|
USART_InitStructure.USART_BaudRate = 9600;
|
205
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
206
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
207
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
208
|
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
209
|
USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
|
210
|
USART_Init(USART1,&USART_InitStructure);
|
212
|
USART_Cmd(USART1,ENABLE);
|
218
|
int fputc(int ch,FILE *f)
|
220
|
USART_SendData(USART1,(u8) ch);
|
221
|
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
|
------------------------------------------------------
2012 11 17 更新
------------------------------------------------------
一直不知道如何给一个嵌入式设备通过公网直接发送信息,因为嵌入式设备没有一个固定的公网IP, 其实可以通过一种逆向的方法来解决,嵌入式设备可以定时向服务器主动提交请求,服务器可以再返回数据或指令,嵌入式设备获取后再分析处理。
这样使用webclient 就可以实现更多的功能,webclient 定时向服务器请求页面,并获取页面返回的代码,就可以分析返回的代码,执行相应程序。
阅读(2299) | 评论(0) | 转发(0) |