1、网络概念
为了能够让不同的计算机之间进行数据共享(分享),就需要在不同的计算机之间建立一种连接,通过某种方式连接在一起的计算机就组成一个网络,在同一网络中的计算机就可以通过一些制定好的规则通信与数据传输b
重点: 连接, 传输
数据传输协议有:
UDP:不可靠的,无连接的服务,传输效率高,效率要求相对高,对准确要求相对低的场景 如在线视频,网络语音电话 =》 dgram(数据报)
TCP : 可靠的,面向连接,传输效率低,效率要求相对低,但对准确性要求相对高的场景 如文件传输,接收文件,远程登录;
2、dgram(数据报)
dgram模块提供了 UDP 数据包 socket 的实现
socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,其本质上就是一套用于实现网络数据交换的接口(API)
使用
const dgram = require('dgram')
服务端部份
const dgram = require('dgram'); const serve = dgram.createSocket('udp4') // udp4 => ipv4 udp6 => ipv6 serve.on('listening', () => { //开始监听端口 const address = serve.address(); console.log(`服务器监听的地址${address.address}端口是${address.port}`) }) serve.on('error', err => { //监听服务器发生的错误 console.log(`系统发生错误${err.stack}`) serve.close(); //关闭系统 }) serve.on('message', (msg, rinfo) => { console.log(`接收到地址为${rinfo.address},端口为${rinfo.port}的信息${msg}`) }) serve.bind(9079, '127.0.0.1') //9079是监听的商品 127.0.0.1是地址
客户端部份
const dgram = require('dgram') const client = dgram.createSocket('udp4') //需要与服务端监听的服务一致 let setEvent = (msg) => { client.send(msg, 9079, '127.0.0.1') //需要与服务端监听的端口和地址一致 } let arr = ['are you ok???', "this is first", 'this is second', 'this is third', 'this is four']; let sendHandle = (msg, time) => { return new Promise(resolve => { setTimeout(() => { setEvent(msg) resolve() }, time) }) } for(let i = 0, len = arr.length; i < len; i ++) { sendHandle(arr[i], i * 1000) }
3、net模块的初步使用
服务端
const net = require('net'); const serve = net.createServer(); serve.on('connection', socket => { console.log('连接了') socket.write('welcome!!!') }) serve.listen(9527, '0.0.0.0') //注意这里的 '0.0.0.0'表示 可以通过 127.0.0.1来访问或者通过ip地址来访问
客户端
const net = require('net'); const client = net.createConnection(9527, '0.0.0.0'); client.on('data', (msg) => { console.log(msg) })
4、http协议
http.clientRequest - options
protocol : 使用的协议。默认为 http:
host : 请求发送至的服务器的域名或 IP 地址。默认为 localhost
family : 当解析 host 和 hostname 时使用的 IP 地址族时有效,值是 4 或 6,未指定时,则同时使用 IP v4 和 v6
port : 远程服务器的端口。默认为 80
method : 指定 HTTP 请求方法的字符串。默认为 'GET'
path : 请求的路径。默认为 '/'。 应包括查询字符串(如有的话)。如 '/index.html?page=12'
headers : 包含请求头的对象
http客户端的写法
const http = require('http') const fs = require('fs') /** * http.ClientRequest客户端请求类 * new http.ClientRequet() * http.request() * 以上两种方式创建客户端请求类 */ //创建一客户端(能发http请求)的对象 //请求行 get http://127.0.0.1:8080/ http/1.1 const client = http.request('http://www.baidu.com', { //tcp参数 // host: 'www.baidu.com', //把地址写在这个地方也可以 port: 80, //http参数 protocol: 'http:', method: 'get', path: '/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png' }, res => { //服务器响应的时候触发 let content = Buffer.alloc(0) //如果遇到图片的情况,最好是用Buffer进行存储 res.on('data', data => { //接收数据 content = Buffer.concat([content, data], content.length + data.length) }) res.on('end', () => { //接收完成后调用 fs.writeFileSync('./baidu.png', content); console.log('保存完成') }) }) client.on('error', (e) => { console.error(`请求遇到问题: ${e.message}`); }); //上面是请求的对象,真正发送请求需要调如下方法 //write里的参数会放置到request.body里面发送过去, 注意这里没有的情况下需要填‘’ client.write('') //发送完成后调用 client.end()
http服务端写法
const http = require('http') // const serve = http.createServer((req, res) => { // res.write('are you ok???') // console.log(req.url) // res.end() // }) const serve = http.createServer(); serve.on('request', (req, res) => { //这里的request本质上就是net.socket + http协议增加的一些内容 //request.socket = net.socket //除此之外,request相当于http.IncomingMessage 类 console.log(req.socket.remoteAddress) console.log(req.url) //相当于客户端的url部份 switch(req.url) { case '/': res.write('index'); break; case '/list': res.write('list'); break; case '/view': res.write('view'); break; default: res.write('404'); break; } res.end(); }) serve.listen(8080) //默认的地址是'0.0.0.0'相当于监听当前电脑的内外网
http请求头信息
HTTP 消息头允许客户端和服务器通过 request和 response传递附加信息。一个请求头由名称(不区分大小写)后跟一个冒号“:”,冒号后跟具体的值(不带换行符)组成。该值前面的引导空白会被忽略;自定专用消息头可通过'X-' 前缀来添加;具体看如下信息
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers
根据不同上下文,可将消息头分为:
一般头: 同时适用于请求和响应消息,但与最终消息主体中传输的数据无关的消息头。
请求头: 包含更多有关要获取的资源或客户端本身信息的消息头。
响应头: 包含有关响应的补充信息,如其位置或服务器本身(名称和版本等)的消息头。
实体头: 包含有关实体主体的更多信息,比如主体长(Content-Length)度或其MIME类型。
常用头信息
Content-Type<实体首部>:发送内容类型 =》 相当是MIME类型,可上网查询MIME类型,决定后端返回的数据格式 如text/ html
Content-Length<实体首部>:发送内容长度
Location<响应首部>:重定向地址
Cookie<请求首部>:包含要发送给服务器的Cookie 客户端
Set-Cookie<响应首部>:服务器端向客户端发送 cookie 服务端
请求头的设置方法
response.statusCode //设置状态码 response.statusMessage //设置状态信息 response.setHeader(name, value) //设置请求头信息 response.writeHead(statusCode[, statusMessage][, headers]) //三者结合 如 response.setHeader('content-type', 'text/html;chartset=utf8')
response.writeHead(301, http.STATUS_CODES[301], { //如果遇到重定向的情况下,浏览器会自动去找location下的地址进行重定向
'content-type': 'text/html;charset=utf8',
'location': 'http://www.baidu.com'
})
注意一些简短的返回信息已经在http.STATUS_CODES中已经定义,具体使用http.
STATUS_CODES[404]进行访问
fs模块与http模块相结构实现自动访问
const http = require('http') const fs = require('fs') const path = require('path') const serve = http.createServer(); serve.on('request', (req, res) => { const dir = path.join(__dirname,'www', req.url); if(!fs.existsSync(dir) || !fs.statSync(dir).isFile()){ res.write('404') res.end(); return; } fs.readFile(dir, (err, data) => { //读取对应目录下的文件 err? res.write('404'): res.write(data); res.end(); }) }) serve.listen(8079)