Nodejs中的网络编程

2018年06月19日 13:39 | 2647次浏览

一、课程介绍

1.1 课程内容

此课程主要讲解TCP和UDP的网络编程,net模块提供了一个异步网络包装器,用于TCP网络编程,它包含了创建服务器和客户端的方法。dgram模块用于UDP网络编程。


1.2 课程知识点


网络编程的基本概念

net模块的使用

dgram模块的使用


1.3 课程环境

Xfce终端

Node.js v4.2.1

gedit/vim:文本编辑



二、实例步骤

2.1 TCP Server

net模块通过net.createServer方法创建TCP服务器,通过net.connect方法创建客户端去连接服务器。

通过net模块创建一个TCP Server:

// server.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer(function(socket) {
    console.log('client connected');

    // 监听客户端的数据
    socket.on('data', function(data) {
        console.log('server got data from client: ', data.toString());
    });
    // 监听客户端断开连接事件
    socket.on('end', function(data) {
        console.log('connection closed');
    });
    // 发送数据给客户端
    socket.write('Hello\r\n');
});

// 启动服务
server.listen(8080, function() {
    console.log('server bound');
});

然后再创建一个客户端:

// client.js

var net = require('net');

// 连接服务器
var client = net.connect({port: 8080}, function() {
    console.log('connected to server');
    client.write('World!\r\n');
});

// 接收服务端的数据
client.on('data', function(data) {
    console.log('client got data from server: ', data.toString());
    // 断开连接
    client.end();
});

// 断开连接
client.on('end', function() {
    console.log('disconnected from server');
});

运行测试:

打开两个终端,先运行TCP服务器代码:

$ node server.js

然后在另一个终端运行TCP客户端代码:

$ node client.js

即可看到两个终端运行结果。


2.2 简易聊天室服务端

了解了基础的东西,下面我们来做一个简单的聊天室吧。

首先创建TCP服务器,和前面一样:

// chatServer.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer();

server.on('error', function(err) {
    console.log('Server error: ', err.message);
});

server.on('close', function() {
    console.log('Server closed');
});

server.listen(8080);

接收客户端连接请求:

// chatServer.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer();

// 新增的代码
server.on('connection', function(socket) {
    console.log('Got a new connection');
});

server.on('error', function(err) {
    console.log('Server error: ', err.message);
});

server.on('close', function() {
    console.log('Server closed');
});

server.listen(8080);

获取客户端发送过来的数据:

// chatServer.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer();

server.on('connection', function(socket) {
    console.log('Got a new connection');
    // 新增的代码
    socket.on('data', function(data) {
        console.log('Got data: ', data);
    });
});

server.on('error', function(err) {
    console.log('Server error: ', err.message);
});

server.on('close', function() {
    console.log('Server closed');
});

server.listen(8080);

既然是聊天室,当然允许多个客户端用户同时连接,所以需要接收所有的用户连接:

// chatServer.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer();
// 新增的代码
var sockets = []; // 存储所有客户端socket

server.on('connection', function(socket) {
    console.log('Got a new connection');

    // 新增的代码
    sockets.push(socket);

    socket.on('data', function(data) {
        console.log('Got data: ', data);
    });
});

server.on('error', function(err) {
    console.log('Server error: ', err.message);
});

server.on('close', function() {
    console.log('Server closed');
});

server.listen(8080);

服务器广播数据,把来自客户端的数据转发送给其他所有客户端:

// chatServer.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer();
var sockets = []; // 存储所有客户端socket

server.on('connection', function(socket) {
    console.log('Got a new connection');

    sockets.push(socket);

    socket.on('data', function(data) {
        console.log('Got data: ', data);

        // 新增代码
        sockets.forEach(function(otherSocket) {
            if (otherSocket !== socket) {
                otherSocket.write(data);
            }
        });
    });
});

server.on('error', function(err) {
    console.log('Server error: ', err.message);
});

server.on('close', function() {
    console.log('Server closed');
});

server.listen(8080);

最后,需要把关闭连接的客户端从服务器广播列表中给删除掉:

// chatServer.js

var net = require('net');

// 创建TCP服务器
var server = net.createServer();
// 存储所有客户端socket
var sockets = [];

server.on('connection', function(socket) {
    console.log('Got a new connection');

    sockets.push(socket);

    socket.on('data', function(data) {
        console.log('Got data: ', data);

        sockets.forEach(function(otherSocket) {
            if (otherSocket !== socket) {
                otherSocket.write(data);
            }
        });
    });

    // 新增代码
    socket.on('close', function() {
        console.log('A client connection closed');
        var index = sockets.indexOf(socket);
        sockets.splice(index, 1);
    });
});

server.on('error', function(err) {
    console.log('Server error: ', err.message);
});

server.on('close', function() {
    console.log('Server closed');
});

server.listen(8080);


2.3 简易聊天室客户端

聊天室的服务端功能基本就实现了,下面我们来写一个简单的客户端吧

// chatClient.js

var net = require('net');

process.stdin.resume();
process.stdin.setEncoding('utf8');

var client = net.connect({ port: 8080 }, function() {
    console.log('Connected to server');

    // 获取输入的字符串
    console.log('input: ');
    process.stdin.on('data', function(data) {
        // 发送输入的字符串到服务器
        console.log('input: ');
        client.write(data);

        // 输入 'close' 字符串时关闭连接
        if (data === 'close\n') {
            client.end();
        }
    });
});

// 获取服务端发送过来的数据
client.on('data', function(data) {
    console.log('Other user\'s input', data.toString());
});

client.on('end', function() {
    console.log('Disconnected from server');
    // 退出客户端程序
    process.exit();
});

客户端中用到了process这个模块,process是一个Node.js的全局模块,可以在任何地方直接使用而无需通过require方法引入。process模块允许你获得或者修改当前Node.js进程的设置。process.stdin用于获取来自标准输入的可读流(Readable Stream)。


现在来运行这个聊天室吧:

$ node chatServer.js

在打开多个终端窗口,运行:

$ node chatClient.js

然后在任意运行的客户端输入字符串并按回车键,会在服务端和其他客户端开到这个客户端的输入内容。这样就实现了一个简单的聊天室了^_^。


2.4 UDP Server

UDP和TCP类似,通过dgram.createSocket创建服务。

UDP服务器:

// udpServer.js

var dgram = require("dgram");

var server = dgram.createSocket("udp4");

server.on("error", function(err) {
    console.log("server error:\n" + err.stack);
    server.close();
});

// 接收来自客户端的消息
server.on("message", function(msg, rinfo) {
    console.log("server got: " + msg.toString() + " from " + rinfo.address + ":" + rinfo.port);
});

// 监听服务
server.on("listening", function() {
    var address = server.address();
    console.log("server listening on " + address.address + ":" + address.port);
});

server.bind(41234);
// server listening 0.0.0.0:41234

UDP客户端:

// udpClient.js

var dgram = require('dgram');

var client = dgram.createSocket('udp4');
var message = new Buffer('hello vxzsk');

client.send(message, 0, message.length, 41234, 'localhost', function(err, bytes) {
    client.close();
});

发送的消息必须通过Buffer创建。

然后运行服务端:

$ node udpServer.js

再运行客户端:

$ node udpClient.js

此时,服务端就会收到来自客户端的消息:

server got: hello vxzsk from 127.0.0.1:59393

Node.js基础的网络编程就讲到这里了。



三、课程总结

1 作为web服务器软件,Node.js提供了net模块用于tcp通信,dgram模块用于udp通信

2 net.createServer()用于创建tcp监听服务器,net.connect()用于客户端连接tcp服务器

3 dgram模块通过dgram.createSocket()创建udp socket,通过bind()监听特定端口,通过send()向特定socket发送信息



四、课后作业

请你用Node.js net模块实现一个下载器,从预先确定的url中下载文件并保存到本地。此作业可能涉及到一些未讲过的知识,请自行查阅资料解决。



小说《我是全球混乱的源头》

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程


上一篇:Nodejs 的http模块 下一篇:Node.js中的进程
^