为了能够让不同的计算机之间进行数据共享(分享),就需要在不同的计算机之间建立一种连接,通过某种方式连接在一起的计算机之间就组成了一个网络,在同一个网络中的计算机就可以通过一些制定好的规则进行通信与数据传输了。
常见的网络连接方式:
一台计算机的数据都是通过网卡等设备进行传输的(发送和接受),那么也就是意味着我们电脑中运行的各种不同的软件使用可能都是同一块网卡;为了解决程序与程序之间数据传输,所以一个应用程序在使用网卡发送和接收数据的时候,需要指定你要监听的网卡(一台机器可能有多块网卡),同时还要指定一个端口号。
类似我们去银行办理业务的窗口,不同的端口为不同的应用程序进行服务,当一个程序需要接收来自某块网卡设备的数据的时候,需要指定监听的端口,同时发送数据到某个地址(网卡)的数据也要指定接收方的端口号发送数据的端口由系统分配 一个应用程序可以同时监听多个网卡的多个端口,一个端口只能同时被一个程序监听,如果一个程序尝试监听一个已经被其他程序监听的端口,就会报端口占用的错误。
TCP、UDP
TCP | UDP |
---|---|
可靠的、面向连接的协议、传输效率低 | 不可靠的、无连接的服务、传输效率高 |
适用于效率要求相对低,但对准确性要求相对高的场景 | 适用于效率要求相对高,对准确性要求相对低的场景 |
应用场景:文件传输、接收邮件、远程登录 | 应用场景:在线视频、网络语音电话 |
dgram模块提供了 UDP 数据包 socket 的实现,socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,其本质上就是一套用于实现网络数据交换的接口(API)。
server.js
// server端
const dgram = require(‘dgram‘);
// 1. 第一种创建socket服务的方式
// const server = new dgram.Socket();
/*
第二种创建方式,其实就是return new dgram.Socket()封装成一个API;
第一个参数是协议类型,udp4表示IPV4,udp6表示IPV6
*/
// const server = dgram.createSocket(‘udp4‘, (data)=>{
// console.log("receive data: ", data.toString());
// });
const server = dgram.createSocket(‘udp4‘);
server.on(‘error‘, err=>{
console.log(`服务器异常: \n${err.stack}`)
server.close();
});
server.on(‘message‘, (msg, rinfo)=> {
console.log(`服务器接收到来自${rinfo.address}:${rinfo.port}的 ${msg}`)
});
server.on(‘listening‘, ()=>{
const address = server.address();
console.log(`服务器监听 ${address.address}: ${address.port}`);
});
/*
2. 监听端口
使用server.bind([port],[,address],[,callback])
port:未指定则由路由系统分配
address:默认0.0.0.0,表示所有地址IP
callback:绑定成功后的回调
*/
server.bind(‘4444‘, ‘127.0.0.1‘)
client.js
// client端
const dgram = require(‘dgram‘);
// 1. 创建socket服务
const server = dgram.createSocket(‘udp4‘);
// 2.发送数据
server.send(‘hello, server‘, ‘4444‘, ‘127.0.0.1‘, () => {
console.log("send data success!");
// 3.关闭服务
server.close();
});
net 模块提供了创建基于流的 TCP 或 IPC 服务器(net.createServer())和客户端(net.createConnection()) 的异步网络 API。
服务端:提供服务,被连接,被请求的一方。
客户端:获取服务,发起连接,请求的一方。
实现一个从server端下载图片到本地的功能。
server.js
/*
在node中,tcp协议基于 net 模块来实现
*/
const net = require(‘net‘);
const fs = require(‘fs‘);
/**
* 创建一个服务器端
* 1. 监听地址以及端口
* 2. 处理发送到当前监听地址以及端口的数据
* 3. 返回/发送 数据到连接的客户端
*
* net.server类
* new net.Server()
* net.createServer() 等于 return new net.Server()
*/
const server = net.createServer(() => {
// 这个函数其实就是connection事件绑定的函数
})
// 当有客户端连接的时候触发
server.on(‘connection‘, socket => {
console.log("Welcome To TCP Server");
// socket.write(‘连接者,你好.‘)
// 发送一个图片给客户端
let data = fs.readFileSync(‘./server/1.jpg‘);
console.log(data.length);
socket.write(data);
socket.end();
/* socket.on(‘data‘, data => {
console.log(socket.remoteAddress, socket.remotePort, data.toString());
}) */
})
// 监听地址以及端口,ip默认为0.0.0.0,表示监听系统网卡的所有地址
server.listen(4444, () => {
console.log("[+] TCP server listen 127.0.0.1:4444...")
});
// server.listen(4444, ‘127.0.0.1‘, () => {
// console.log("[+] TCP server listen 127.0.0.1:4444...")
// });
client.js
const net = require(‘net‘);
const fs = require(‘fs‘);
/**
* 创建客户端与udp不同
* net.Socket 类
*
* 1. new net.Socket()
* 2. net.createConnection()
*/
let buf = [];
// 要连接的目标主机地址以及端口号
const clientSocket = net.createConnection(4444, ‘127.0.0.1‘);
clientSocket.write(‘hello‘);
// 监听数据传输
clientSocket.on(‘data‘, data => {
// console.log(data.toString());
// 这个地方触发2次是因为分包的原因
console.log("pic data: ", data);
console.log(data.length);
buf.push(data);
})
clientSocket.on(‘end‘, () => {
console.log(‘数据包接收完成!‘);
// 拼装buffer数据
// console.log(`---------------------\n${buf}`);
imgBufferData = Buffer.concat(buf);
console.log("Buffer Data: \n", imgBufferData)
console.log(imgBufferData.length);
// /*
// 把接收到的数据组合起来吗,然后通过fs写入到client文件夹中
// 注意:我们接收到的数据是buffer
// 保存写入buffer数据到文件
// */
if (!fs.existsSync(__dirname + ‘/client‘)) {
fs.mkdirSync(‘./client‘);
}
try {
fs.writeFileSync(‘./client/01.jpg‘, imgBufferData)
} catch (error) {
console.log("err: ", error);
}
const picData = fs.readFileSync(‘./client/01.jpg‘);
console.log("01.jpg二进制数据长度: ", picData.length);
})
功能如下:
原文:https://www.cnblogs.com/alexander3714/p/14055364.html