通过前面相关的学习已经具备编写自己HTTP服务器的能力,不管是通过阻塞还是非阻塞的方式都可以实现。但是这里需要对HTTP协议进行一个了解。
当用户打开浏览器,输入一个URL地址,就能收到远程HTTP服务器发送过来的网页。浏览器就是最常见的HTTP客户程序。
HTTP协议规定,HTTP请求由3部分构成,分别是:
请求方式、URI、HTTP协议的版本请求头请求正文下面是一个HTTP请求的例子:
GET / HTTP/1.1Host: www.google.com.hkConnection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36X-Chrome-UMA-Enabled: 1X-Client-Data: CJS2yQEipbbJAQjEtskBCOKYygEI+5zKAQipncoBAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdch, brAccept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4Cookie: NID=98=EmnQgFsnopWExg1XEQNjPR1FKwTo1T7Qk5fH94bdjmUqIdJ6L9C_LLziCX8_UcDv_iyo84kOgKMPTnP0pbfuJqigpoxfDWouhyKX58J_gn2HU1abg7UJFik2bhwSHIU9kpJIEvQ6rtigHffscUqanx5_Tb-F1yq_4WiaBGjINA_A9siROY-WPTka8eRvElgyXk7koHQKGET / HTTP/1.1
分别表示 请求方式(GET) URI(/) 协议版本(HTTP/1.1) 根据HTTP协议,HTTP请求可以使用多种方式:
请求头: 请求头包含许多有关客户端环境和请求正文的有用信息。例如,请求头可以申明浏览器类型,所用的语言,请求正文的类型,已经请求正文的长度。
Host: www.google.com.hkConnection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36X-Chrome-UMA-Enabled: 1X-Client-Data: CJS2yQEIpbbJAQjEtskBCOKYygEI+5zKAQipncoBAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdch, brAccept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4Cookie: NID=98=EmnQgFsnopWExg1XEQNjPR1FKwTo1T7Qk5fH94bdjmUqIdJ6L9C_LLziCX8_UcDv_iyo84kOgKMPTnP0pbfuJqigpoxfDWouhyKX58J_gn2HU1abg7UJFik2bhwSHIU9kpJIEvQ6rtigHffscUqanx5_Tb-F1yq_4WiaBGjINA_A9siROY-WPTka8eRvElgyXk7koHQK请求正文:
HTTP协议规定,请求头和请求正文之间必须以空行分给(只有CRLF[就是回车(CR, ASCII 13, /r) 换行(LF, ASCII 10, /n)。]符号的行),这个空行表示请求头已经结束,接下来是请求正文。下面是POST请求方式提交的表单数据
username=weixin&passWord=1234与HTTP请求相比,HTTP响应格式也由3部分构成:
HTTP协议版本、状态码、描述响应头(Response Header)响应正文(Response Content)下面是一个HTTP响应的例子:
HTTP/1.1 200 OKDate: Sun, 05 Mar 2017 04:31:31 GMTExpires: -1Cache-Control: private, max-age=0Content-Type: text/html; charset=UTF-8Server: gwsX-XSS-Protection: 1; mode=blockX-Frame-Options: SAMEORIGINAlt-Svc: quic=":443"; ma=2592000; v="36,35,34"Transfer-Encoding: chunkedHTTP协议的版本、状态码、描述
HTTP响应的第一行包括服务器使用的HTTP协议的版本,状态码、以及对状态的代码的描述。这三项以空格分开。HTTP/1.1 200 OK
状态码:
状态码是一个3位整数,以1、2、3、4或5开头。
1XX :信息提示,表示临时的响应。2XX:响应成功,表示服务器成功接收了客户端的请求。3XX:重定向。4XX:客户端错误,表明客户端请求了不正确的资源或请求格式错误。5XX:服务器错误,表明服务器由于遇到某种错误而不能响应客户请求。以下是一些常见的状态码:
200:响应成功。400:错误的请求。客户发送的HTTP请求不正确。404:文件不存在。在服务端没有客户端请求的文档。405:服务器不支持客户端的请求方式。500:服务器内部错误。响应头: 响应头也和请求头一样包含许多有用的信息。例如,服务器类型,正文类型。
Content-Type: text/html; charset=UTF-8Server: gws请求正文 在上面的响应格式中没有列出响应正文,因为是通过chrome查看的。chrome将响应正文放到另外的地方,因为响应正文一般都比较大。如下图 通过HTTP响应头与响应正文之间必须用空行分隔。
通过ServerSocketChannel
、SocketChannel
、Buffer
以及线程池实现:
访问方式 在浏览器输入 http://localhost/login.html 出现login页面,输入username和password。
在服务端控制台输出如下:
这个图的请求数据就是完整的包含:请求方式,URI、协议版本、请求头、请求正文。
欢迎关注微信公众号 在路上的coder
每天分享优秀的java技术文章,还有学习视频分享! 扫描二维码关注:
新闻热点
疑难解答