Socket总结 node搭建简单的http服务器
网络中的进程
socket解决的是网络中进程间的通信,其首要解决的就是如何在网络中找到目标进程,这就要求进程拥有唯一性的索引,方便查找连接。
一台机器上,进程与进程之间通行,以PID作为唯一标识。但是在网络中,不同的机器,PID可能重复。
然而,网络层的IP 可以唯一标识主机,传输层的 tcp协议和端口号 则能够唯一标识主机中的进程。
因此: ip地址+协议+端口 = 网络中的一个进程
socket
就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。
socket位于应用层和传输层之间的一个抽象层,封装传输层的各种复杂操作,提供几个简单的接口供应用层调用。
socket的主要作用是实现在网络中 进程之间的通信。
服务端和客户端 统一使用 socket提供的api进行通信。
socket三次握手 (TCP)
client客户端调用 connect()
方法时,即开始进行建立tcp连接(三次握手)中的 第一次握手(阻塞等待服务端的第二次握手)。
server服务端开始调用 accept()
方法,完成 第二次握手(阻塞等待客户端的第三次握手)。
client客户端 connect()
方法收到第二次握手,进行 第三次握手 ,connect()
方法完成执行。
server服务端 accept()
方法收到第三次握手,完成执行。
通信
socket使用的 “ 打开 -> 读写 -> 关闭 ” 这种模式进行的操作。
这种模式将socket看成一个特殊的 “文件”,提供一些函数对其进行 “IO操作”。
服务端和客户端通过读取这个中间 “文件” 来进行通信。
具体的I/O操作函数有一下几种方式
read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()
node中的socket编程
node中跟socket相关的网络模块有两个:
net
http
net为最底层,以事件驱动机制将socket的接口进行封装,提供socket的相关操作。
http在net的基础上,基于http协议进行再一次封装,将请求分成http头和http体,提供基于request和response的基本操作。
net模块
net模块是node的原生模块,是对tcp层的封装(socket)。
提供了两个类的定义:
net.Socket (实现node中的socket操作)
- 事件: ‘lookup’
- 事件: ‘connect’
- 事件: ‘data’
- 事件: ‘end’
- 事件: ‘timeout’
- 事件: ‘drain’
- 事件: ‘error’
- 事件: ‘close’
net.Server (基于socket,再次封装成服务端API)
- 事件: ‘listening’
- 事件: ‘connection’
- 事件: ‘close’
- 事件: ‘error’
提供了一些基于两个类的基本操作
net.createServer([options], [connectionListener])
net.connect(options, [connectionListener])
net.createConnection(options, [connectionListener])
net.connect(port, [host], [connectListener])
net.createConnection(port, [host], [connectListener])
net.connect(path, [connectListener])
net.createConnection(path, [connectListener])
服务端使用
var net = require('net');var server = net.createServer(function(clientSocket){...
})server.listen(10000,'127.0.0.1',function(){console.log('监听开始')
})
客户端使用
var net = require('net');var clientSocket = net.connect({port:10000,host:'127.0.0.1'
},function(){console.log('tcp连接建立成功');
})
...
其中具体的通信使用事件驱动机制。
clientSocket.on('data',function(){...
})
...
http模块
http模块在net的基础上,提供针对应用层http协议的专门API。
http模块以request和response为基本操作单位,封装net.Socket,将获取到的数据data,分成请求头和请求体。
提供了五个类的定义:
http.Server (基于net.Server的再次封装)
- 事件: ‘request’
- 事件: ‘connection’
- 事件: ‘close’
- 事件: ‘checkContinue’
- 事件: ‘connect’
- 事件: ‘upgrade’
- 事件: ‘clientError’
http.ServerResponse (基于net.Socket的再次封装)
- 事件:’close’
http.ClientRequest (基于net.Socket的再次封装)
- 事件: ‘response’
- 事件: ‘socket’
- 事件: ‘connect’
- 事件: ‘upgrade’
- 事件: ‘continue’
http.Agent
http.IncomingMessage
服务端使用
var http = require('http');var server = http.createServer(function(request,response){...
})// 或者var server = new http.Server();
server.on('request',function(request,response){...
})server.listen(10000,'127.0.0.1',function(){console.log('监听开始')
})
客户端使用
var http = require('http');var request = http.request({host : '127.0.0.1',method : 'GET',path: '/'..
})request.on('response',function(response){...
})
url模块
url模块常常配合http模块,对url进行处理。
url.parse(string).query|url.parse(string).pathname || || |------ -------------------
http://localhost:8888/start?foo=bar&hello=world--- -----| || |querystring(string)["foo"] ||querystring(string)["hello"]
通过url模块,可以创建一个路由机制
var http = require('http');
var url = require('url');
var querystring = require('querystring');var routeHandle = {};routeHandle['/'] = function(response){...
}routeHandle['/upload'] = function(response){...
}http.createServer(function(request,response){var pathname = url.parse(request.url).pathname;route(routeHandle,pathname,request,response);}).listen(10000,'127.0.0.1');function route(handle,pathname,request,response){if (typeof handle[pathname] === 'function') {handle[pathname](response);} else {console.log("该路由没有处理器: " + pathname);}
}
静态文件处理
一个完整的http服务器,除了几个特定的url路径处理之外(即后台action),还应该对静态文件请求做处理。
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');var MIME = {"css": "text/css","gif": "image/gif","html": "text/html","ico": "image/x-icon","jpeg": "image/jpeg","jpg": "image/jpeg","js": "text/javascript","json": "application/json","pdf": "application/pdf","png": "image/png","svg": "image/svg+xml","swf": "application/x-shockwave-flash","tiff": "image/tiff","txt": "text/plain","wav": "audio/x-wav","wma": "audio/x-ms-wma","wmv": "video/x-ms-wmv","xml": "text/xml"}...function route(handle,pathname,request,response){// path.extname(relPath) 获取文件后缀名if(path.extname(pathname)){// 静态文件 处理doStaticFile(pathname,response);}else{// action 处理...}
}function doStaticFile(relPath,response){fs.exists(relPath,function(exists){if(!exists){response.writeHead(404, {'Content-Type': 'text/plain'});response.write("请求的路径不存在:" + relPath);response.end();}else{fs.readFile(relPath,'binary',function(err,file){if(err){// 服务器异常response.writeHead(500, {'Content-Type': 'text/plain'});response.end();}else{// 返回静态文件var suffix = path.extname(realPath);// 由于extname返回值包含”.”,所以通过slice方法来剔除掉”.”var mime = MIME[suffix.slice(1)] || 'text/plain';response.writeHead(200, {'Content-Type': mime});response.write(file, "binary");response.end();}})}})}http.createServer(function(request,response){var pathname = url.parse(request.url).pathname;route(routeHandle,pathname,request,response);}).listen(10000,'127.0.0.1');
这里就基本实现了一个http服务器,但在静态文件的处理上还有所欠缺。
对于静态资源的请求,每次都是通过读取文件,当请求过多时,会损坏硬盘IO。
因此需要使用缓存,从而减轻硬盘的IO损坏。
参考博文:
简单理解Socket - Samaritans - 博客园
Socket通信原理和实践 - 张勤一 - 博客频道 - CSDN.NET
深入浅出NodeJS——数据通信,NET模块运行机制 | 小胡子哥的个人网站
net模块中文API
http模块中文API
详解Node.js的http模块之http模块概述 - IT笔录
Http模块 – JavaScript 标准参考教程(alpha)
用NodeJS打造你的静态文件服务器 - CNode技术社区
Socket总结 node搭建简单的http服务器相关推荐
- python搭建web服务器_Python搭建简单的web服务器
Python搭建简单的web服务器 1.win+R输入cmd打开命令行 2.通过 cd 进入到你保存 HTML 文件的目录.例如:H:\D3\d3 输入 cd\ 指令进入到C盘的根目录.(CD(更改目 ...
- 开发板搭建简单的Web服务器
开发板搭建简单的Web服务器 BOA服务器是一个小巧高效的web服务器,是一个运行于Linux或unix下的,支持CGI.适合于嵌入式的单任务的服务器,源代码开放,性能高 BOA是非常小巧的web服务 ...
- 使用VLC media player搭建简单的流媒体服务器
作为程序员,很多时候需要测试流媒体服务功能,VLC media player就可以轻松的将视频.本机画面.笔记本摄像头的内容发布为流媒体服务,在其他网络联通的地方访问,下面只说主要过程. 首先安装VL ...
- 新狼邮箱服务器,搭建简单的邮件服务器+动态域名在互联网中使用
利用server2003搭建简单的邮件服务器,使用动态域名做mx记录可以在互联网中使用,开始之前我copy了一些资料让大家了解一下pop3和smtp. POP3(Post Office Protoco ...
- Ubuntu 搭建简单的Web服务器
Ubuntu 搭建简单的Web服务器 一.搭建工具 二.搭建步骤 2.1Apche工具安装 2.2打开火狐浏览器 三.实现文件浏览功能 一.搭建工具 在这个实验上我用的是apche搭建的web服务 ...
- PC上搭建简单的FTP服务器(仅用于局域网)
PC上搭建简单的FTP服务器(仅用于局域网) 转载请附原文链接:http://blog.fandong.me/2017/07/16/PC-FTP/ 第一步:打开控制面板选择卸载程序(查看方式为类别) ...
- FTP服务器安装+NGINX搭建简单的图片服务器(Linux)
ftp+nginx实现简单的图片服务器 最近在做个人网站,设计到图片的上传和保存,于是想做一个专门存图片的服务器.以前用过一个tomcat web服务器做图片的服务器,但缺点就是必须和部署系统在同一台 ...
- Flask搭建简单图片识别服务器
Flask搭建简单手写数字识别服务器 困惑我好几天的问题终于解决了,基础还是不太牢固啊,特写这篇文档记录一下,一步一步的开始用flask搭建分类服务器,主要分类MNIST数据集,从客户端(这里指浏览器 ...
- Unity搭建简单的图片服务器
具体要实现的目标是:将图片手动拷贝到服务器,然后在Unity中点击按钮将服务器中的图片加载到Unity中. 首先简答解释下 WAMP(Windows + Apache + Mysql + PHP),一 ...
最新文章
- 【HTML】兴唐第二十八节课之初识HTML
- 68页PPT教你撰写一篇优秀的机器学习研究论文!
- 第三百二十七天 how can I 坚持
- CV之MTCNN:MTCNN算法过程及其相关思路配图集合
- 【linux家常菜】redhat 6.5 安装yum
- DevExpress第三方控件汉化的全部代码和使用方法
- token在浏览器和服务端接收和发送
- 经典面试题|讲一讲JVM的组成
- photoshop cs5快捷键的用法总结
- 历时两年,微软物联网安全服务 Azure Sphere 全面上线!
- 【云周刊】第173期:直击数博|阿里胡晓明:用100亿的投入撬动1000亿的脱贫效应...
- Windows 命令行基础(博主推荐)
- LINUX修改网卡MAC地址
- 斜度符号标注_机械图纸尺寸标注规则
- Qt程序实现自动重启
- c#重写TabControl控件实现关闭按钮的方法
- 最长上升子序列(LIS)题目合集
- 写给人类的机器学习 一、为什么机器学习重要
- win10系统要求配置_观察者系统还原游戏配置要求高吗?Observer: System Redux硬件一览!...
- 零基础该怎样开始学编程?