【原创】HTTP协议分析之ARM编程

        HTTP协议是基于请求/响应范式的。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为,统一资源标识符、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
  许多HTTP通讯是由一个用户代理初始化的并且包括一个申请在源服务器上资源的请求。最简单的情况可能是在用户代理(UA)和源服务器(O)之间通过一个单独的连接来完成

       首先,简单介绍基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接。

        在WWW中,“客户”与“服务器”是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。WWW服务器运行时,一直在TCP 80端口(WWW的缺省端口)监听,等待连接的出现。

<UC/OS-II + LWIP1.2.0 源程序>

#define  HTTP_PORT    80

void HttpEntry(void *arg)
{
 extern void Handler_HTTP(struct netconn *pstConn);
 
 struct netconn *pstConn, *pstNewConn;
 
 pstConn = netconn_new(NETCONN_TCP);
 netconn_bind(pstConn, NULL, HTTP_PORT);
 netconn_listen(pstConn);
 
 while(TRUE)
 {
  pstNewConn = netconn_accept(pstConn);
  
  if(pstNewConn != NULL)
  {   
   Handler_HTTP(pstNewConn);
   while(netconn_delete(pstNewConn) != ERR_OK)
    OSTimeDlyHMSM(0, 0, 1, 0);
  }
 }

}

1.建立连接  

       连接的建立是通过申请套接字(Socket)实现的。客户打开一个套接字并把它约束在一个端口上,如果成功,就相当于建立了一个虚拟文件。以后就可以在该虚拟文件上写数据并通过网络向外传送。

2.发送请求
  打开一个连接后,客户机把请求消息送到服务器的停留端口上,完成提出请求动作。
  HTTP/1.0  请求消息的格式为:
  请求消息=请求行(通用信息|请求头|实体头)CRLF[实体内容]
  请求 行=方法 请求URL HTTP版本号 CRLF
  方  法=GET|HEAD|POST|扩展方法
  U R L=协议名称+宿主名+目录与文件名
  请求行中的方法描述指定资源中应该执行的动作,常用的方法有GET、HEAD和POST。不同的请求对象对应GET的结果是不同的,对应关系如下:
  对象      GET的结果
  文件      文件的内容
  程序      该程序的执行结果
  数据库查询   查询结果
  HEAD——要求服务器查找某对象的元信息,而不是对象本身。
  POST——从客户机向服务器传送数据,在要求服务器和CGI做进一步处理时会用到POST方法。POST主要用于发送HTML文本中FORM的内容,让CGI程序处理。
  下面为我测试的时候,通过串口打出来的信息:
GE T   /   H T T P / 1 . 1 
A c c e p t :   i m a g e / g i f ,   i m a g e / x - x b i t m a p ,   i m a g e / j p e g ,   i m a g e / p j p e g ,   a p p l i c a t i o n / x - s h o c k w a v e - f l a s h ,   a p p l i c a t i o n / v n d . m s - e x c e l ,   a p p l i c a t i o n / v n d . m s - p o w e r p o i n t ,   a p p l i c a t i o n / m s w o r d ,   * / * 
A c c e p t - L a n g u a g e :   z h - c n 
A c c e p t - E n c o d i n g :   g z i p ,   d e f l a t e 
U s e r - A g e n t :   M o z i l l a / 4 . 0   ( c o m p a t i b l e ;   M S I E   6 . 0 ;   W i n d o w s   N T   5 . 1 ;   S V 1 ;   M a x t h o n ;   . N E T   C L R   2 . 0 . 5 0 7 2 7 ) 
H o s t :   1 9 2 . 1 6 8 . 1 . 2 
C o n n e c t i o n :   K e e p - A l i v e
  头信息又称为元信息,即信息的信息,利用元信息可以实现有条件的请求或应答。
  请求头——告诉服务器怎样解释本次请求,主要包括用户可以接受的数据类型、压缩方法和语言等。
  实体头——实体信息类型、长度、压缩方法、最后一次修改时间、数据有效期等。
  实体——请求或应答对象本身。

3.发送响应
  服务器在处理完客户的请求之后,要向客户机发送响应消息。
  HTTP/1.0的响应消息格式如下:
  响应消息=状态行(通用信息头|响应头|实体头) CRLF 〔实体内容〕
  状态行=HTTP版本号 状态码 原因叙述
  状态码表示响应类型
  1××  保留
  2××  表示请求成功地接收
  3××  为完成请求客户需进一步细化请求
  4××  客户错误
  5××  服务器错误
  响应头的信息包括:服务程序名,通知客户请求的URL需要认证,请求的资源何时能使用。

<UC/OS-II + LWIP1.2.0 源程序>

/*
* By Small.Box at 2006.10.18 
*
* RFC2616
* 1xx: Informational - Request received, continuing process
* 2xx: Success - The action was successfully received,understood, and accepted
* 3xx: Redirection - Further action must be taken in order to complete the request
* 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
* 5xx: Server Error - The server failed to fulfill an apparently valid request
*
* Status-Code =
*
* 其中最常见的几种错误和正确状态代码有
*
* "100"  ; Continue
* "200"  ; OK
* "404"  ; Not Found
*
*/

#define  HTTP_HTML_HEADER  "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n"

netconn_write(httpConn, HTTP_HTML_HEADER, strlenExt(HTTP_HTML_HEADER), NETCONN_COPY);

4.关闭连接
  客户和服务器双方都可以通过关闭套接字来结束TCP/IP对话.

下面是通过IE浏览器点击WEB页面后,传给ARM的数据值。

PO S T   / h e S e t N e t C F G P a r a m   H T T P / 1 . 1 
A c c e p t :   i m a g e / g i f ,   i m a g e / x - x b i t m a p ,   i m a g e / j p e g ,   i m a g e / p j p e g ,   a p p l i c a t i o n / x - s h o c k w a v e - f l a s h ,   a p p l i c a t i o n / v n d . m s - e x c e l ,   a p p l i c a t i o n / v n d . m s - p o w e r p o i n t ,   a p p l i c a t i o n / m s w o r d ,   * / * 
R e f e r e r :   h t t p : / / 1 9 2 . 1 6 8 . 1 . 2 / 
A c c e p t - L a n g u a g e :   z h - c n 
C o n t e n t - T y p e :   a p p l i c a t i o n / x - w w w - f o r m - u r l e n c o d e d 
A c c e p t - E n c o d i n g :   g z i p ,   d e f l a t e 
U s e r - A g e n t :   M o z i l l a / 4 . 0   ( c o m p a t i b l e ;   M S I E   6 . 0 ;   W i n d o w s   N T   5 . 1 ;   S V 1 ;   M a x t h o n ;   . N E T   C L R   2 . 0 . 5 0 7 2 7 ) 
H o s t :   1 9 2 . 1 6 8 . 1 . 2 
C o n t e n t - L e n g t h :   4 6 
C o n n e c t i o n :   K e e p - A l i v e 
C a c h e - C o n t r o l :   n o - c a c h e 
  
i p = 1 9 2 . 1 6 8 . 1 . 3 & n m = 2 5 5 . 2 5 5 . 2 5 5 . 0 & g w = 1 9 2 . 1 6 8 . 1 . 1

以上数据,也是通过ARM串口截获出来的。下面我将给出IE-WEB页面的源程序,WEB页面的源代码是用HTML语言和JavaScript语言写的。

<JavaScript 和HTML 语言 源代码>

<html>
 <title>
  终端配置
 </title>
 <META NAME="Author" CONTENT="Small.Box">
 
<!------------------------------JavaScript 程序------------------------------>
<SCRIPT LANGUAGE="JavaScript">
/*
*******************************************************************************
*        以下JavaScript语言编写的程序
*
*Description: 处理WEB界面上一些参数的设置是否正确
*
*Note  : V1.0 by Small.Box at 2006.10.19
*
*******************************************************************************
*/ 
function PrintfErroInfo(Info)
{
  switch(Info) {
   case 1:
     alert("请输入正确的IP地址!");
     break;
   case 2:
     alert("请输入正确的子网掩码!");
     break;
   case 3:
     alert("请输入正确的网关地址!");
     break;
   default:
     break;          
   
  }   
}
 
function check(para,inTpye)
{
 var ipArray,j;
 if(/[A-Za-z_-]/.test(para.value)){
  PrintfErroInfo(inTpye);
  para.focus();
  return false;
 }
 else{
  ipArray = para.value.split(".");
  j = ipArray.length
  if(j!=4)
  {
   PrintfErroInfo(inTpye);
   para.focus();
   return false;
  }
 
  for(var i=0;i<4;i++)
  {
   if(ipArray[i].length==0 || ipArray[i]>255)
   {
    PrintfErroInfo(inTpye);
    para.focus();
    return false;
   }
  }
 }

 return true;
}
 
function checkIP()
{
 ip = document.getElementById('ip');
 if(!check(ip,1))
  return false;
 nm = document.getElementById('nm');
 if(!check(nm,2))
  return false;
 gw = document.getElementById('gw');
 if(!check(gw,3))
  return false;
 
 return true;
}

/*
*******************************************************************************
*        以下JavaScript语言编写的程序
*
*Description: 现实当地具体时间
*
*Note  : V1.0 by Small.Box at 2006.10.19
*
*******************************************************************************
*/ 
function initialize()
{
 tick();
}

function showLocale(objD)
{
   var dn,s;
   var hh = objD.getHours();
   var mm = objD.getMinutes();
   var ss = objD.getSeconds();
   s = objD.getFullYear() + "年" + (objD.getMonth() + 1) + "月" + objD.getDate() +"日 ("+ nStr1[objD.getDay()] +")";

   if(hh>12) {
     hh = hh-12; dn = '下午';
   }
   else
     dn = '上午';

   if(hh<10) hh = '0' + hh;
   if(mm<10) mm = '0' + mm;
   if(ss<10) ss = '0' + ss;

   s += " " + dn + ' ' + hh + ":" + mm + ":" + ss;
   return(s);
}

function tick()
{
   var today;
   today = new Date();
   LocalTime.innerHTML = showLocale(today);
   window.setTimeout("tick()", 1000);
}

</SCRIPT>
<!------------------------------JavaScript 程序结束------------------------------>

 

<!---------------------------------HTML程序开始---------------------------------->
<body bgcolor = 99FF66 >

<hr size=1>
 <h2 align = "center"> 参数配置 </h2>
  <h3 align = "right">
    <FONT size=2 style="FONT-SIZE: 9pt"> <B> 本地时间: </B> </FONT>
    <SPAN id=LocalTime style="COLOR: #000080; FONT-FAMILY: Arial; FONT-SIZE: 9pt"> 0000年0月0日 ( ) 午 00:00:00 </SPAN>
  </h3>  
<hr size=1>

<p>
<!--
 <fieldset>
  <legend>用户名和密码:</legend>    
  <input id="hiddenField" name="hiddenField" type="hidden" value="hiddenvalue" />
  <label for="username">用户名:</label>
  <input type="text" id="username" name="username" value="dreamdu" size="15" maxlength="25" />
  <label for="pass">密码:</label>
  <input type="password" id="pass" name="pass" size="15" maxlength="25" />
  <input type="file" id="myimage" name="myimage" size="35" maxlength="255" />
  
 </fieldset>
-->

<form method=post action="/heSetNet" name="ipform" οnsubmit="return checkIP();">
        终端IP地址:<input type="text" id= "IPAddr" name="ip" size="20" maxlength=15 class="ed">
<br>
        子网掩码  :<input type="text" id= "ZWYM"   name="nm" size="20" maxlength=15 class="ed">
<br>
        终端GW地址:<input type="text" id= "WGAddr"  name="gw" size="20" maxlength=15 class="ed">

        <input type="submit" value="提 交" class="bt">
</form>

</p>
</BODY>
</HTML>

通过以上的讲解,能明白了整个HTTP协议的一个大体过程,具体的详细的过程,请参考RFC标准吧,呵呵……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值