server 简易实现

今天的学习简单的了解了服务器,写好脚本,用node.js把自己电脑当做服务器,(1号)一个窗口执行node.js脚本命令,(2号)另一个窗口执行请求,成功了就把1号窗口的脚本内容返回到2号窗口中显示

TCP 传输控制协议(Transmission Control Protocol)

TCP 和 UDP 的区别是什么

简答:TCP 可靠、面向连接、相对 UDP 较慢;UDP 不可靠,不面向连接、相对 TCP 较快。搞定。

TCP 的三次握手指的是什么

简答:每次建立连接前,客户端和服务端之前都要先进行三次对话才开始正式传输内容,三次对话大概是这样的:

1. 客户端:我要连接你了,可以吗

2. 服务端:嗯,我准备好了,连接我吧

3. 客户端:那我连接你咯。

4. 开始后面步骤

IP 网络协议(英语:Internet Protocol)

只要你在互联网中,那么你就会有一个 IP。通俗上理解,IP 分为「内网 IP」 和「外网 IP」,以下图为例:


你从电信那里买来带宽,一年一千多。

电信为你提供 DNS 服务。

你买了一个路由器,然后用电脑和手机分别连接路由器广播出来的无线 WIFI。

只要路由器连上电信的服务器,那么路由器就会有一个「外网 IP」,比如「14.17.32.211」就是一个外网 IP。这就是你在互联网中的地址。

但是如果你重启路由器,那么你很有「可能」被重新分配一个「外网 IP」,也就是说 你的路由器没有「固定的外网 IP」

你可以花每年几千块钱租用一个「固定的外网 IP」,但是显然不会这么浪费钱。像腾讯、阿里这样的大公司租用了很多外网 IP,这样才能对我们提供稳定的服务。

但是有个问题,你的路由器的外网 IP 如果是14.17.32.211,那么你的手机和电脑的 IP 又是什么呢?答案是「内网 IP」

路由器会在你家里创建一个内网,内网中的设备使用内网 IP,一般来说这个 IP 的格式都是 192.168.xxx.xxx。

一般路由会给自己分配一个好记的内网 IP,如 192.168.1.1

然后路由会给每一个内网中的设备分配一个不同的内网 IP,如电脑是 192.168.1.2,手机是 192.168.1.3,以此类推。

现在路由器有两个 IP,一个外网 IP(14.17.32.211)和一个内网 IP(192.168.1.1)

内网中的设备可以互相访问(比如你可以用电脑或手机进入 http://192.168.1.1 来查看你的路由器),但是不能直接访问外网,内网设备想要访问外网,就必须经过路由器中转。

外网中的设备可以互相访问(比如 qq.com 可以把首页发送给你的路由器,你的路由器有外网 IP),但是外网中的设备无法访问你的内网设备(这很好理解,内网是一个封闭的网络,外人进不来,所以实际上 qq.com 无法直接把首页放送给你的电脑和手机)

问题来了,那 qq.com 是怎么把首页发送到我的手机上的呢?答案是通过路由器来中转。

路由器接收到 qq.com 的页面后,把页面发送给你的电脑或手机。路由器知道如何给这些信息指路,路由器就是一个指路人,这就是「路由」两个字的来历。

路,就是「必由之路」中的路。由,就是「必由之路」中的由(由是经过、缘由的意思)。所有的信息都要经过路由器,然后被指向一条它该去的路。

也就是说内网和外网就像两个隔绝的空间,无法互通,唯一的联通点就是路由器(因为路由器既有外网 IP 也有内网 IP),所以路由器有时候也被叫做「网关」,这个「关」是「一夫当关,万夫莫开」的「关」。如果路由器到电信的连接中断了,那么内网中所有的设备也就无法上网了。(这很好理解,相当于唯一一条出去的路断了)

除了内网 IP 和外网 IP,还有两个特别特殊的 IP,就是本地 IP:127.0.0.1。本地 IP 永远表示设备自己。不信你可以 ping 127.0.0.1 一下,会发现只需要 0.01 ms 就得到了响应(你 ping qq.com 需要几十毫秒才得到响应)

默认情况下,hosts 文件里会有一行127.0.0.1 localhost,意思就是 localhost 指向 127.0.0.1,所以 localhost 也表示设备自己。不信你 ping localhost 试试,会发现实际上是在 ping 127.0.0.1

还有一个特别特殊的 IP:0.0.0.0,它不表示任何设备。这个 IP 不同的地方含义不同,以后我们会用到,用到的时候再说意思。

端口

你想要访问一个设备(前提是你使用的是 TCP 或 UDP 协议。还记得吗,HTTP 就使用了 TCP),只指定 IP 是不够的,还必须指定端口(Port)。

端口其实就是一个编号,并不是一种硬件。

一个服务器(硬件)不一定只提供一种服务,比如一个服务器既提供 HTTP 服务,又提供 FTP 服务,还提供 SMTP 服务(邮件服务),那么只用一个 IP 是无法告诉服务器你想要使用哪种服务。

所以这里有一个重要的原则:一个端口对应一个服务。

比如

要提供 HTTP 服务你最好使用 80 端口(能不能使用别的端口?可以,不过不建议你违反约定)

要提供 HTTPS 服务你最好使用 443 端口(能不能使用别的端口?可以,不过不建议你违反约定)

要提供 FTP 服务你最好使用 21 端口(能不能使用别的端口?可以,不过不建议你违反约定)

问题1:我怎么知道应该使用什么端口?

维基百科 把 0 到 1023 号端口对应的服务都告诉你了,点进去看看吧。

问题2:一共由多少端口?

每个机器一共有 65535(2的16次方减1)个端口(这是协议规定的)。不过这些端口的使用由一些规定

0 到 1023(2的10次方减1)号端口是留给系统使用的,你只有拥有了管理员权限后,才能使用这 1024 个端口。

其他端口可以给普通用户使用

如果一个端口正在提供服务,也就是被占用了,那么就不能再使用这个端口。除非你先停掉正在占用这个端口的服务。以后你们会经常遇到这个问题。

总结

上面都是 TCP/IP 相关的知识,如果你记不住,就记住下面这句话:

使用 HTTP 协议访问另一个 IP 时,必须同时提供 IP 和端口号,缺一不可。

那么问题来了

我访问 http://qq.com 时并没有提供端口号,为什么我依然可以访问

答:因为浏览器帮你加了默认端口号 80。

Node.js 服务器

接收请求

我们的脚本只需要一个文件就可以搞定

新建一个安全的目录,不需要我重复强调吧?

cd ~/Desktop; mkdir node-demo; cd node-demo

touch server.js

编辑 server.js

运行 node server 或者 node server.js,看到报错

根据报错提示调整你的命令

成功之后,这个 server 会保持运行,无法退出

如果你想「中断」这个 server,按 <kb>Ctrl</kbd> + <kbd>C</kbd> 即可(C 就是 Cancel 的意思)

中断后你才能输入其他命令

我建议你把这个 server 放在那里别动,新开一个 Bash 窗口,完成下面的教程

好了服务器完成。只不过

这个服务器目前只有一个功能,那就是打印出路径和查询字符串

还缺少一个重要的功能,那就是发出 HTTP 响应

目前我们先只做一个功能玩玩。

接下来你要发起一个请求到这个服务器。这听起来有点怪异,「我向自己发起请求」,目前是的,因为你买不起服务器啊。

在新的 Bash 窗口运行 curl http://localhost:你的指定的端口/xxx 或者 curl http://127.0.0.1:你指定的端口/xxx。

你会马上发现 server 打印出了路径:

这说明我们的 server 收到了我们用 curl 发出的请求

由于 server 迟迟没有发出响应,所以 curl 就一直等在那里,无法退出(用 <kb>Ctrl</kbd> + <kbd>C</kbd> 中断这个傻 curl)

发出响应

接下来我们让我们 server 发出响应

编辑 server.js

在中间我标注的区域添加两行代码

response.write('Hi')

response.end()

中断之前的 server,重新运行 node server 8888

curl http://127.0.0.1:8888/xxx,结果如下:

Hi%

这个 % 不是我们的内容,% 表示结尾。别再问我了。如果你看 % 不爽,就把 'Hi' 换成 'Hi\n'。

好了,响应添加成功

使用 curl -s -v -- "http://localhost:8888/xxx" 可以查看完整的请求和响应(上节课的内容)

根据请求返回不同的响应

用户请求 / 时,返回 html 内容

该 html 内容里面由一个 css link 和一个 script

css link 会请求 /style.css,返回 css 内容

script 会请求 /main.js,返回 js 内容

请求 / /style.css /main.js 以外的路径,则一律返回 404 状态码

上传代码供以后复习


var http = require('http')

var fs = require('fs')

var url = require('url')

var port = process.argv[2]

if(!port){

  console.log('请指定端口号好不啦?\nnode server.js 8888 这样不会吗?')

  process.exit(1)

}

var server = http.createServer(function(request, response){

  var parsedUrl = url.parse(request.url, true)

  var path = request.url

  var query = ''

  if(path.indexOf('?') >= 0){ query = path.substring(path.indexOf('?')) }

  var pathNoQuery = parsedUrl.pathname

  var queryObject = parsedUrl.query

  var method = request.method

  /******** 从这里开始看,上面不要看 ************/

  console.log('HTTP 路径为\n' + path)

  if(path == '/style.css'){

    response.setHeader('Content-Type', 'text/css; charset=utf-8')

    response.write('body{background-color: #ddd;}h1{color: red;}')

    response.end()

  }else if(path == '/main.js'){

    response.setHeader('Content-Type', 'text/javascript; charset=utf-8')

    response.write('alert("这是JS执行的")')

    response.end()

  }else if(path == '/'){

    response.setHeader('Content-Type', 'text/html; charset=utf-8')

    response.write('<!DOCTYPE>\n<html>'  +

      '<head><link rel="stylesheet" href="/style.js">' +

      '</head><body>'  +

      '<h1>你好</h1>' +

      '<script src="/script.html"></script>' +

      '</body></html>')

    response.end()

  }else{

    response.statusCode = 404

    response.end()

  }

  /******** 代码结束,下面不要看 ************/

})

server.listen(port)

console.log('监听 ' + port + ' 成功\n请用在空中转体720度然后用电饭煲打开 http://localhost:' + port)


版权出自饥人谷,禁止转载

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,894评论 2 89
  • 名词延伸 通俗的说,域名就相当于一个家庭的门牌号码,别人通过这个号码可以很容易的找到你。如果把IP地址比作一间房子...
    杨大虾阅读 20,586评论 2 57
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,093评论 0 3
  • ctrl+z把正在运行的程序调到后台,暂停一个前台的作业,即挂起 。 ctrl+x在某些文字处理程序中,这个控制字...
    christinazou阅读 196评论 0 0