在线时间234 小时
UID3301905
注册时间2017-1-8
NXP金币112
TA的每日心情 | 开心 2018-4-20 15:04 |
---|
签到天数: 8 天 [LV.3]偶尔看看II
金牌会员
- 积分
- 2953
- 最后登录
- 2023-7-24
|
本帖最后由 donatello1996 于 2019-3-31 20:23 编辑
【1768】串口驱动&HTML简单的网页服务器演示
之前忙于别的事情没空发帖,今晚都补回来,不多说废话。
得益于论坛里的大佬们都造好轮子,我可以省下很多探索工作,直接用@story_xjj大佬的TCP通信例程来做一个基于TCP通信的HTML网页服务器,应用层为HTTP。
TCP通信部分非常简单,只需要初始化EMAC外设和UIP协议即可。UIP在例程中频繁出现,可以推断这是基于LPC1768的TCP简化协议,类似于STM32的LWIP协议,代码如下:
- while(!tapdev_init());
- uip_init();
- uip_ethaddr.addr[0] = EMAC_ADDR0;
- uip_ethaddr.addr[1] = EMAC_ADDR1;
- uip_ethaddr.addr[2] = EMAC_ADDR2;
- uip_ethaddr.addr[3] = EMAC_ADDR3;
- uip_ethaddr.addr[4] = EMAC_ADDR4;
- uip_ethaddr.addr[5] = EMAC_ADDR5;
- uip_setethaddr(uip_ethaddr);
- uip_ipaddr(ipaddr,169,254,122,15);
- uip_sethostaddr(ipaddr);
- uip_ipaddr(ipaddr,169,254,122,1);
- uip_setdraddr(ipaddr);
- uip_ipaddr(ipaddr, 255,255,0,0);
- uip_setnetmask(ipaddr);
- uip_listen(HTONS(8888));
复制代码
需要包含以下文件:
还有一点需要注意的是,UIP协议的特性是半双工互确认通信,与完整的TCP/IP协议相比精简了全双工部分,即开发板一般是做服务器充当接收方,需要发送方上位机手动绑定端口,收发共用一个套接字(socket),严格执行先收后发的操作,即客户端上位机发送TCP报文,开发板再回应TCP报文,而不像Windows或者Linux系统那样集成了全双工、双线程收发独立TCP通信,因为全双工TCP通信是需要两个套接字来实现的,并且在一个进程中需要开辟两个线程,这个对于单片机来说没有必要,何况TCP全双工场合使用得非常少,像这次的网页服务器演示Demo,仅需要半双工通信即可。在之后的TCP上位机通信中,上位机需要定期发送TCP报文以告诉开发板,开发板收到报文之后再返回规定信息,这个也是只需要半双工通信即可。 在HTTP通信中,以HTTP 1.0协议为例,客户端发送GET请求,里面包含了浏览器版本信息,语言信息,连接方式等,默认连接方式为KEEP-ALIVE即持续通信,这个方式确保了客户端在与服务器创建了TCP端口通道之后,服务器可多次POST(发送)HTML报文,报文送回客户端中,重新解析成网页,如果方式不为持续通信的话,那么客户端就只能发出一次请求,而服务器只能POST回应一次了,这个在绝大多数的网页服务器应用中都不合常理。
我做了个网页服务器,使用的方法为GET,客户端浏览器每发送一次GET请求(刷新一次浏览器),开发板端都会做计数:
代码如下:
- unsigned char flag_post_once=0,flag_keep_alive=0;
- char buf_html_head[100]={"\
- HTTP/1.1 200 OK\nContent-Length:00047\nServer: Hatschi Server 1.0\nContent-Type: text/html\n\n\
- "};
- char buf_html[200]={"\
- <html>\
- <head>\
- <title>IRD1768网页服务器</title>\
- </head>\
- <body>\
- <p>网页服务器计数简单实验</p>\
- <p>论坛昵称:donatello1996</p>\
- <p>计数值:0000</p>\
- </body>\
- </html>"};
- //i=127,227
- static count=0;
- void mytcp_appcall()
- {
- struct mytcp_state *s = &(uip_conn->appstate);
- int len,i,j,len_buf_html;
- char *nptr,buf_html_send[300];
- if(uip_connected())
- {
- PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
- }
- if(uip_conn->lport == HTONS(8888))
- {
- if(uip_newdata())
- {
- len=uip_datalen();
- nptr=(char*)uip_appdata;
- if(len < UIP_SEND_BUF_MAX_LEN)
- {
- printf("8888:%d %s\n",len,nptr);
- if(nptr[0]=='G'&&nptr[1]=='E'&&nptr[2]=='T')
- {
- count++;
- printf("客户端浏览器发出GET请求\n");
- flag_post_once=1;
- }
- else if(nptr[0]=='P'&&nptr[1]=='O'&&nptr[2]=='S'&&nptr[3]=='T')
- {
- }
- for(i=0;i<=1000;i++)
- {
- if(nptr[i]=='H'&&nptr[i+1]=='T'&&nptr[i+2]=='T'&&nptr[i+3]=='P'&&
- nptr[i+4]=='/')
- {
- printf("HTTP协议版本/类型:");
- for(j=i;j<=i+7;j++)
- putchar(nptr[j]);
- putchar('\n');
- }
- if(nptr[i]=='H'&&nptr[i+1]=='o'&&nptr[i+2]=='s'&&nptr[i+3]=='t')
- {
- printf("主机地址及端口号:");
- for(j=i+6;j<=i+22;j++)
- putchar(nptr[j]);
- putchar('\n');
- }
- if(nptr[i]=='C'&&nptr[i+1]=='o'&&nptr[i+2]=='n'&&nptr[i+3]=='n'&&
- nptr[i+4]=='e'&&nptr[i+5]=='c'&&nptr[i+6]=='t'&&nptr[i+7]=='i'&&
- nptr[i+8]=='o'&&nptr[i+9]=='n')
- {
- printf("连接方式:");
- for(j=i+12;j<=i+21;j++)
- putchar(nptr[j]);
- putchar('\n');
- flag_keep_alive=1;
- }
- if(flag_post_once&&flag_keep_alive)
- {
- printf("对客户端浏览器发出的GET请求作出回应\n");
- flag_keep_alive=0,flag_post_once=0;
- len_buf_html=strlen(buf_html);
- buf_html_head[31]=len_buf_html/10000%10+'0';
- buf_html_head[32]=len_buf_html/1000%10+'0';
- buf_html_head[33]=len_buf_html/100%10+'0';
- buf_html_head[34]=len_buf_html/10%10+'0';
- buf_html_head[35]=len_buf_html%10+'0';
-
- buf_html_head[227]=count/1000%10+'0';
- buf_html_head[228]=count/100%10+'0';
- buf_html_head[229]=count/10%10+'0';
- buf_html_head[230]=count%10+'0';
- strcat(buf_html_send,buf_html_head);
- strcat(buf_html_send,buf_html);
- uip_send(buf_html_send,strlen(buf_html_send));
- strcpy(buf_html_send,"");
-
- }
- }
- }
- }
- }
复制代码
硬件连接如下,电脑端使用网口连接开发板,设置与开发板同一网段的IP地址:
上传工程文件:
LPC1768.zip
(3.49 MB, 下载次数: 19)
|
|