Web服務(wù)器20190530

自己寫(xiě)一個(gè)Web服務(wù)器

  • 在此之前需要先了解一些東西巷送。

一蕴忆、網(wǎng)絡(luò)與IP

HTTP 協(xié)議的底層其實(shí)是由 TCP 協(xié)議和 IP 協(xié)議(簡(jiǎn)稱(chēng) TCP/IP)構(gòu)建的。

TCP傳輸控制協(xié)議(Transmission Control Protocol)
TCP協(xié)議的特點(diǎn)是:
面向連接、點(diǎn)對(duì)點(diǎn)(一對(duì)一)颤绕、可靠交付、面向字節(jié)流祟身,也就是說(shuō)僅僅把上層協(xié)議傳遞過(guò)來(lái)的數(shù)據(jù)當(dāng)成字節(jié)傳輸奥务。
為了實(shí)現(xiàn)TCP上述的特點(diǎn),TCP協(xié)議需要解決的是面向連接(建立連接和關(guān)閉連接的方式)袜硫、可靠傳輸(錯(cuò)誤確認(rèn)和重傳)氯葬、流量控制(發(fā)送方和接收方的傳輸速率協(xié)調(diào))、擁塞控制四個(gè)方面婉陷。
IP網(wǎng)絡(luò)協(xié)議(Internet Protocol)
只要你在互聯(lián)網(wǎng)中帚称,那么你就會(huì)有一個(gè) IP。通俗上理解秽澳,IP 分為「內(nèi)網(wǎng) IP」和「外網(wǎng) IP」

  • 什么是外網(wǎng)IP闯睹?
    例如,你買(mǎi)了一個(gè)路由器担神,只要路由器連接上了電信的服務(wù)器楼吃,那么路由器就會(huì)有一個(gè)「外網(wǎng) IP」,比如「14.17.32.211」就是一個(gè)外網(wǎng) IP。這就是你在互聯(lián)網(wǎng)中的地址孩锡。
  • 什么是內(nèi)網(wǎng)IP酷宵?
    答案就是你的電腦和手機(jī)的IP,路由器會(huì)在你家里創(chuàng)建一個(gè)內(nèi)網(wǎng)躬窜,內(nèi)網(wǎng)中的設(shè)備使用內(nèi)網(wǎng) IP忧吟,一般來(lái)說(shuō)這個(gè) IP 的格式都是 192.168.xxx.xxx。
    一般路由會(huì)給自己分配一個(gè)好記的內(nèi)網(wǎng) IP斩披,如 192.168.1.1
    然后路由會(huì)給每一個(gè)內(nèi)網(wǎng)中的設(shè)備分配一個(gè)不同的內(nèi)網(wǎng) IP溜族,如電腦是 192.168.1.2,手機(jī)是 192.168.1.3垦沉,以此類(lèi)推煌抒。
    現(xiàn)在路由器有兩個(gè) IP,一個(gè)外網(wǎng) IP(14.17.32.211)和一個(gè)內(nèi)網(wǎng) IP(192.168.1.1)
    內(nèi)網(wǎng)中的設(shè)備可以互相訪問(wèn)(比如你可以用電腦或手機(jī)進(jìn)入 http://192.168.1.1 來(lái)查看你的路由器)厕倍,但是不能直接訪問(wèn)外網(wǎng)寡壮,內(nèi)網(wǎng)設(shè)備想要訪問(wèn)外網(wǎng),就必須經(jīng)過(guò)路由器中轉(zhuǎn)讹弯。外網(wǎng)中的設(shè)備也是這樣况既。

二、端口

  • 你想要訪問(wèn)一個(gè)設(shè)備组民,只指定IP是不夠的棒仍,還必須在指定端口。
  • 端口其實(shí)就是一個(gè)編號(hào)臭胜,并不是一種硬件莫其。一個(gè)服務(wù)器(硬件)不一定只提供一種服務(wù),比如一個(gè)服務(wù)器既提供 HTTP 服務(wù)耸三,又提供 FTP 服務(wù)乱陡,還提供 SMTP 服務(wù)(郵件服務(wù)),那么只用一個(gè) IP 是無(wú)法告訴服務(wù)器你想要使用哪種服務(wù)仪壮。
    所以這里有一個(gè)重要的原則:一個(gè)端口對(duì)應(yīng)一個(gè)服務(wù)憨颠。
    問(wèn)題一:我怎么知道應(yīng)該使用什么端口?
    答:維基百科可以告訴你积锅,點(diǎn)進(jìn)去看看吧爽彤。
    問(wèn)題二:一共由多少端口?
    答:每個(gè)機(jī)器一共有 65535(2的16次方減1)個(gè)端口(這是協(xié)議規(guī)定的)乏沸。
    不過(guò)這些端口的使用由一些規(guī)定:
    1淫茵、 0 到 1023(2的10次方減1)號(hào)端口是留給系統(tǒng)使用的爪瓜,你只有擁有了管理員權(quán)限后蹬跃,才能使用這 1024 個(gè)端口。
    2、其他端口可以給普通用戶使用蝶缀。
    3丹喻、如果一個(gè)端口正在提供服務(wù),也就是被占用了翁都,那么就不能再使用這個(gè)端口碍论。除非你先停掉正在占用這個(gè)端口的服務(wù)。以后你們會(huì)經(jīng)常遇到這個(gè)問(wèn)題柄慰。
    問(wèn)題三:我訪問(wèn) http://qq.com 時(shí)并沒(méi)有提供端口號(hào)鳍悠,為什么我依然可以訪問(wèn)?
    答:因?yàn)?strong>瀏覽器幫你加了默認(rèn)端口號(hào) 80。

三坐搔、一個(gè)簡(jiǎn)易Server

1藏研、服務(wù)器你已經(jīng)有了,你使用的電腦就是你的服務(wù)器概行。
2蠢挡、但是你還沒(méi)有提供 HTTP 服務(wù)的「程序」,用腳本就可以提供 HTTP 服務(wù)凳忙,例如Node.js腳本业踏。

Node.js服務(wù)器

  1. 新建一個(gè)安全的目錄
    cd ~/Desktop
    mkdir node-demo
    cd node-demo
  2. touch server.js
  3. 編輯 server.js,內(nèi)容如下:
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]

if(!port){
  console.log('請(qǐng)指定端口號(hào)好不啦?\nnode server.js 8888 這樣不會(huì)嗎涧卵?')
  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

  /******** 從這里開(kāi)始看勤家,上面不要看 ************/



  console.log('得到 HTTP 路徑\n' + path)
  console.log('查詢字符串為\n' + query)
  console.log('不含查詢字符串的路徑為\n' + pathNoQuery)



  /******** 代碼結(jié)束,下面不要看 ************/
})

server.listen(port)
console.log('監(jiān)聽(tīng) ' + port + ' 成功\n請(qǐng)用在空中轉(zhuǎn)體720度然后用電飯煲打開(kāi) http://localhost:' + port) 

4.運(yùn)行node server.js
5.根據(jù)報(bào)錯(cuò)提示調(diào)整你的命令
6.成功之后柳恐,這個(gè) server 會(huì)保持運(yùn)行却紧,無(wú)法退出

  • 如果你想「中斷」這個(gè) server,按 Ctrl C即可(C 就是 Cancel 的意思)
  • 中斷后你才能輸入其他命令
  • 建議把這個(gè) server 放在那里別動(dòng)胎撤,新開(kāi)一個(gè) Bash 窗口晓殊,完成下面的教程好了服務(wù)器完成。

7.這個(gè)服務(wù)器目前只有一個(gè)功能伤提,那就是打印出路徑和查詢字符串巫俺。
8.在新的 Bash 窗口運(yùn)行 curl http://localhost:你的指定的端口/xxx 或者 curl http://127.0.0.1:你指定的端口/xxx。你會(huì)馬上發(fā)現(xiàn) server 打印出了路徑:

圖片.png

9.這說(shuō)明我們的 server 收到了我們用 curl 發(fā)出的請(qǐng)求

10.由于 server 遲遲沒(méi)有發(fā)出響應(yīng)肿男,所以 curl 就一直等在那里介汹,無(wú)法退出(用 Ctrl+C中斷 curl)
發(fā)出響應(yīng)
接下來(lái)讓我們的server 發(fā)出響應(yīng)
1.編輯 server.js
2.在中間標(biāo)注的區(qū)域添加兩行代碼
response.write('Hi')
response.end()
3.中斷之前的 server,重新運(yùn)行 node server.js 8888
4.curl http://127.0.0.1:8888/xxx舶沛,結(jié)果如下:
Hi%
(這里注意嘹承,Windows系統(tǒng)可能有不一樣的結(jié)果,例如下圖如庭,原因我暫未知

圖片.png

這個(gè) % 不是我們的內(nèi)容叹卷,% 表示結(jié)尾。如果你不喜歡 % ,就把 'Hi' 換成 'Hi\n'骤竹。
5.好了帝牡,響應(yīng)添加成功
6.使用 curl -s -v -- "http://localhost:8888/xxx" 可以查看完整的請(qǐng)求和響應(yīng)。

下面是一個(gè)完整的例子:

var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]

if(!port){
  console.log('請(qǐng)指定端口號(hào)好不啦蒙揣?\nnode server.js 8888 這樣不會(huì)嗎贮尉?')
  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

  /******** 從這里開(kāi)始看粱栖,上面不要看 ************/

  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 == '/script.js'){
    response.setHeader('Content-Type', 'text/javascript; charset=utf-8')
    response.write('alert("這是JS執(zhí)行的")')
    response.end()
  }else if(path == '/index.html'){
    response.setHeader('Content-Type', 'text/html; charset=utf-8')
    response.write('<!DOCTYPE>\n<html>'  + 
      '<head><link rel="stylesheet" href="/style.css">' +
      '</head><body>'  +
      '<h1>你好</h1>' +
      '<script src="/script.js"></script>' +
      '</body></html>')
    response.end()
  }else{
    response.statusCode = 404
    response.end()
  }

  /******** 代碼結(jié)束,下面不要看 ************/
})

server.listen(port)
console.log('監(jiān)聽(tīng) ' + port + ' 成功\n請(qǐng)用在空中轉(zhuǎn)體720度然后用電飯煲打開(kāi) http://localhost:' + port)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市斜姥,隨后出現(xiàn)的幾起案子礁遣,更是在濱河造成了極大的恐慌部翘,老刑警劉巖河闰,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異锨匆,居然都是意外死亡崭别,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)恐锣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茅主,“玉大人,你說(shuō)我怎么就攤上這事土榴【饕Γ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玷禽,是天一觀的道長(zhǎng)赫段。 經(jīng)常有香客問(wèn)我,道長(zhǎng)矢赁,這世上最難降的妖魔是什么糯笙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮撩银,結(jié)果婚禮上给涕,老公的妹妹穿的比我還像新娘。我一直安慰自己额获,他們只是感情好够庙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著抄邀,像睡著了一般耘眨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上境肾,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天剔难,我揣著相機(jī)與錄音胆屿,去河邊找鬼。 笑死钥飞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衫嵌。 我是一名探鬼主播读宙,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼楔绞!你這毒婦竟也來(lái)了结闸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤酒朵,失蹤者是張志新(化名)和其女友劉穎桦锄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蔫耽,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡结耀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匙铡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图甜。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鳖眼,靈堂內(nèi)的尸體忽然破棺而出黑毅,到底是詐尸還是另有隱情,我是刑警寧澤钦讳,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布矿瘦,位于F島的核電站,受9級(jí)特大地震影響愿卒,放射性物質(zhì)發(fā)生泄漏缚去。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一琼开、第九天 我趴在偏房一處隱蔽的房頂上張望病游。 院中可真熱鬧,春花似錦稠通、人聲如沸衬衬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滋尉。三九已至,卻和暖如春飞主,著一層夾襖步出監(jiān)牢的瞬間狮惜,已是汗流浹背高诺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碾篡,地道東北人虱而。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像开泽,于是被迫代替她去往敵國(guó)和親牡拇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 名詞延伸 通俗的說(shuō)剔蹋,域名就相當(dāng)于一個(gè)家庭的門(mén)牌號(hào)碼,別人通過(guò)這個(gè)號(hào)碼可以很容易的找到你辅髓。如果把IP地址比作一間房子...
    楊大蝦閱讀 20,602評(píng)論 2 57
  • 今天的學(xué)習(xí)簡(jiǎn)單的了解了服務(wù)器泣崩,寫(xiě)好腳本,用node.js把自己電腦當(dāng)做服務(wù)器洛口,(1號(hào))一個(gè)窗口執(zhí)行node.js腳...
    夜景闌姍閱讀 464評(píng)論 0 0
  • 轉(zhuǎn)載自:http://blog.csdn.net/u010391029/article/details/48311...
    Chris_Zheng閱讀 1,401評(píng)論 0 2
  • 這一刻的回眸 就是期待 與詩(shī)結(jié)緣 和你邂逅
    品墨悟道閱讀 121評(píng)論 0 0
  • 你習(xí)慣了什么律想,就在哪里成長(zhǎng)——一百天閱讀33本書(shū),第三十一本 《習(xí)慣領(lǐng)域》 八個(gè)擴(kuò)展習(xí)慣領(lǐng)域的方法 01绍弟、虛心地積...
    怪獸老板的解憂雜貨鋪閱讀 568評(píng)論 0 0