http服务器开发笔记(一)——先跑起来
做了很多年的web相关开发,从来也没有系统的学习http协议,最近正好工作不怎么忙,准备系统的学习一下。
接下来准备自己写一小型的http服务器来学习,因为现在对JavaScript比较熟悉,所以决定用node.js来编写。
实际上node.js已经内置http服务器的相关接口直接调用就能处理http相关请求啦(nodejs的http文档),但我要从头开发所以不使用这个接口,而是直接操作socket来开发。
node.js的socket相关接口在net包里面,下面先让服务器运行起来,先上代码。
代码使用了es6语法,不了解的朋友可以看看阮一峰写的教程ECMAScript 6 入门;如果对http协议也不了解可以看看《图解HTTP》这本书。
// httpserver.js
const net = require('net') // 建立socket服务器
const server = net.createServer() // 监听网络连接请求
server.on('connection', (socket) => { // 监听socket接收数据事件
socket.on('data', (data)=> { // 响应实体数据
data = Buffer.from('你好! HTTP') // 响应首部数据
head =
`
HTTP/1.1 200 OK
Content-Length: ${data.length}
Content-Type: text/html
`
content = `${head}\r\n\r\n${data.toString()}`// 返回响应数据
socket.end(content)
})
}) // 监听9001端口
server.listen(9001, () => {
console.log('opened server on', server.address())
})
在命令行输入 node httpserver.js 这样一个最简单的http服务器就运行起来了,在本机浏览器访问 localhost:9001 看看是不是显示了 “你好! HTTP”。
这段代码一共做了这么几件事:
- 建立一个socket服务器,监听9001端口的请求
- 监听网络连接请求
- 生成http响应首部字段和响应实体数据
对于http来说最重要的就是生成http响应数据了,下面一张显示了http请求和响应数据的格式
下面这段就是响应报文首部:
HTTP/1.1 200 OK // 告诉浏览器服务器支持HTTP/1.1 返回码200表示请求被正常处理 (返回码有很多以后会用到)
Content-Length: ${data.length} // 返回数据的长度(字节)
Content-Type: text/html // 返回内容的数据类型(返回数据类型也有很多以后也会用到)
有几点必须注意:
- 字段间换行符用的是\r\n,从每二行开始头和换行符之间千万不要加空格或其它不可见字符,我在几个主流浏览器上测试没有一个能正常解析的。
加空格是这个样子
不加空格是这个样子
- 字段Content-Length单位是字节,如果返回报文主体数据时包含中文,不能直接使用String的length属性,length会把1个汉字长度认为是1会显示不全。这个字段不加的话大多数浏览器也能正确显示, 如果长度不对会显示不全。
报文首部下面就是报文主体了,首部和主体之间也是就\r\n分割的,主体和换行符之间什么字符都不要加,否则会把字符算到报文主体里面。
到这里可能会有疑问,既然都用\r\n分割那么如何判断哪个是报文首部哪个是主体部分呢,其实主体前面有两对\r\n,浏览器就是根据这个判断的。
可以只用一对\r\n试试,会看到浏览器不会正常显示 “你好! HTTP”的。
转载请注明出处:http://www.cnblogs.com/oliverliye/p/6424188.html
http服务器开发笔记(一)——先跑起来的更多相关文章
- 流媒体服务器开发笔记(2)--RTCP协议介绍
http://blog.sina.com.cn/s/blog_53061af00100o2no.html ——————————————————————————————————————————————— ...
- C++服务器开发之笔记三
为什么需要原子性操作? 我们考虑一个例子:(1)x++这个常见的运算符在内存中是怎样操作的?从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址 若是有两个线程同时对同一个变量++, ...
- RK3568开发笔记(五):在虚拟机上使用SDK编译制作uboot、kernel和ubuntu镜像
前言 buildroot虽然灵活,但是基于实际情况,本身是侧重驱动和应用定制开发的只定制一次文件系统投入有点多,还不如直接ubunt自己交叉编译依赖库,做一些库的移植裁剪. 于是本篇就使用ubu ...
- 开发笔记:基于EntityFramework.Extended用EF实现指定字段的更新
今天在将一个项目中使用存储过程的遗留代码迁移至新的架构时,遇到了一个问题——如何用EF实现数据库中指定字段的更新(根据UserId更新Users表中的FaceUrl与AvatarUrl字段)? 原先调 ...
- Lucene/Solr搜索引擎开发笔记 - 第1章 Solr安装与部署(Jetty篇)
一.为何开博客写<Lucene/Solr搜索引擎开发笔记> 本人毕业于2011年,2011-2014的三年时间里,在深圳前50强企业工作,从事工业控制领域的机器视觉方向,主要使用语言为C/ ...
- 安卓开发笔记——自定义广告轮播Banner(实现无限循环)
关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...
- 微信公众号开发笔记(C#)
这篇文章还不错,使用 .net , 对微信用户的想公众号发送的文字进行回复.比较简单,自己可以修改更复杂的回复. 微信公众号开发笔记(C#) 原文地址 需求分析 根据用户在微信上发送至价值中国公众号 ...
- IOS开发笔记(4)数据离线缓存与读取
IOS开发笔记(4)数据离线缓存与读取 分类: IOS学习2012-12-06 16:30 7082人阅读 评论(0) 收藏 举报 iosiOSIOS 方法一:一般将服务器第一次返回的数据保存在沙盒里 ...
- 【Cocos2d-x游戏引擎开发笔记(25)】XML解析
原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/9128819 XML是一种非常重要的文件格式,由于C++对XML的支持非常完善 ...
随机推荐
- JQuery 根据ID在页面中定位
1.锚点跳转简介 锚点其实就是可以让页面定位到某个位置上的点.在高度较高的页面中经常见到.比如百度的百科页面,wiki中的page内容. 我知道实现锚点的跳转有两种形式,一种是a标签+name属性:还 ...
- Supervisor: A Process Control System
Supervisor: 进程控制系统 概述:Supervisor是一个 Client/Server模式的系统,允许用户在类unix操作系统上监视和控制多个进程,或者可以说是多个程序. 它与launch ...
- [刷题]算法竞赛入门经典(第2版) 4-7/UVa509 - RAID!
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa509 - RAID! #include<iostream> ...
- linux vi 报错 E37: No write since last change (add ! to override)
用 vi 命令编辑文本文件,没有文件写入权限的时候会报这个错.:q :wq 怎么都不能退出. 这时只需 ctrl+z 即可,或者在退出命令后加 ! 忽略提示 :q!
- javascript设计模式详解之策略模式
接上篇命令模式来继续看下js设计模式中另一种常用的模式,策略模式.策略模式也是js开发中常用的一种实例,不要被这么略显深邃的名字给迷惑了.接下来我们慢慢看一下. 一.基本概念与使用场景: 基本概念:定 ...
- XSS攻击及预防
跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻击者往Web页面里插 ...
- vue2入坑随记(一)
都说Vue2简单,上手容易,但小马过河,自己试了才晓得,除了ES6语法和webpack的配置让你感到陌生,重要的是思路的变换,以前随便拿全局变量和修改dom的锤子不能用了,变换到关注数据本身.vue的 ...
- 学习笔记TF009:对数几率回归
logistic函数,也称sigmoid函数,概率分布函数.给定特定输入,计算输出"success"的概率,对回题回答"Yes"的概率.接受单个输入.多维数据或 ...
- 一次基于Vue.Js用户体验的优化
.mytitle { background: #2B6695; color: white; font-family: "微软雅黑", "宋体", "黑 ...
- QT修改UI和源码后,程序页面还是原来页面的解决方法
发生原因: 移植了一个Qt程序在修改完QT的cpp源码和UI界面布局等内容后,重启点击QT Creator左下角的运行(Ctrl+R)编译程序并启动后,程序界面及修改内容并没有改变. 解决方式: 找到 ...