Node的聊天室

Node

//on 为事件 enevt
//方法 ()   ; 直接 用.
//属性 无括号;直接 用.
变量 白色的;
 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。let定义局部变量
Socket就是端口号 加  url
 
\r是回车,英文是Carriage return,表示使光标下移一格
\n是换行,英文是New line,表示使光标到行首
测试:https://www.runoob.com/quiz/python-quiz.html

Node聊天室完成版

var sockSa = []  //定义用户存放(地)点
const net = require('net');  //导入模块,给一个常量
const server = net.createServer(function (sock) {  //创建服务器
    console.log('连接')
    sockSa.push(sock)   //把sock=客户端socket放在数组里面
    console.log('这是所有sock的个数:'+ sockSa.length)
    // console.log(sockSa)
    sock.on('end',function(){
        console.log('断开')
    });
    sock.on('data', (data) => {
        data = data.toString()
        console.log(data);  //在服务端显示,数据以字符串输出
        // 判断是否是第一句话
        //sock.name = data
        if(sock.name == null ){
            data = data.slice(0,3)
            console.log(data.length)
            sock.name = data
            return
        }
        if (data[0]=='@') {
            //取名字
            var at = data.match(/@\w{3}/)[0].slice(1);
            //打出说的话私聊对他说的话。
            console.log('@' + at + 'say:' + data.slice(4))

            for (var i = 0; i < sockSa.length; i++) {
                if (at == sockSa[i].name) {
                    sockSa[i].write(sock.name + ''+at +' say:' + data.slice(4))
                    //把接收到的数据分发给单人。
                }
            }
        }else{
            for(var i= 0; i<sockSa.length ;i++){
                if(sock==sockSa[i] ){
                    continue;  //如果出现了指定的条件,然后继续循环中的下一个迭代。
                }else{
                    sockSa[i].write(sock.name+'对大家说:' + data)
                    //把接收到的数据分发给每个人。(广播功能)
                }

            }
        }
    })
});
server.on('error',(er) => {
    throw er;           //对于报错不发
});
server.listen(8889,()=>{
    console.log('绑定上8889')
})



//--------------------------客户端


process.stdin.setEncoding('utf8'); //格式
const net = require('net');   //加载net的模块
var client = new net.Socket();   //客户端的socket

client.on('data', (data) => {     //net下socket的事件,data是变量
    console.log(data.toString());//收到服务器返回的数据
});

client.on('end', () => {
    console.log('退出聊天');
});

client.on('connect',()=>{
    console.log('连接成功!')
    process.stdin.on('readable', () => {
        let chunk;  //定义局部 变量

        while ((chunk = process.stdin.read()) !== null) {
            // if(chttps://www.runoob.com/nodejs/nodejs-net-module.html
            client.write(chunk)
            //死循环 就是你可以输入,我服务端可以接受
        }
    });
});

client.connect(8889,'127.0.0.1')

const net = require('net');
var users = {};
// var count = 0
const server = net.createServer(function (socket) {
    const id = socket.remoteAddress +  socket.remotePort

    users[id] = {
        nickname :"匿名",
        socket
    };

    console.log(users[id].nickname+'上线')

    server.getConnections((err, connect) => {
        // count = connect
        socket.write('你好,当前在线用户'+connect+'')
        console.log('当前在线用户'+connect+'')
        for (let v_id in users) {
            if (v_id !== id){
                users[v_id].socket.write(users[id].nickname+'上线')
                users[v_id].socket.write('当前在线用户'+connect+'')
            }
        }
    })

    socket.setEncoding('utf8');
    socket.on('data',function (data) {
        data = data.replace(/[\r\n]/g,"");
        var flag = data.slice(0,1);
        switch (flag) {
            case '#':{
                let s = ''
                for (let v_id in users) {
                    s += [users[v_id].nickname + "   "]
                }
                socket.write('当前用户表:'+s)
                break;
            }
            case '@':{
                let t = data.slice(1).split(' ');
                let text = t[1];
                let toUser = t[0]
                let toSocket = null
                for (let v_id in users){
                    if (users[v_id].nickname === toUser) {
                        toSocket = users[v_id];
                        break;
                    }
                }
                if (toSocket) {
                    toSocket.socket.write(users[id].nickname+':'+text)
                } else {
                    socket.write('对不起,你输入的用户名不存在!')
                }
                break;
            }
            case '!':{
                let text = data.slice(1);
                users[id].nickname = text;
                socket.write('修改成功!');
                break;
            }
            default :{
                let text = data.slice(0);
                for (let v_id in users) {
                    if (v_id !== id) {
                        users[v_id].socket.write(users[id].nickname+':'+text)
                    }
                }
            }
        }
    });
    socket.on('end',function (){
        count = Object.keys(users).length
        outman = users[id].nickname

        for (let v_id in users) {
            if (v_id !== id){
                users[v_id].socket.write(outman +'离开')
                users[v_id].socket.write('在线人数:'+ (count-1))
            }
        }
        console.log(outman +'离开')
        console.log('在线人数:'+ (count-1))
        delete users[id]
        console.log(count-1)
        // })

    })
});

server.on('error', (er) => {
    throw er;           //对于报错不发
});
server.listen(8889, () => {
    console.log('绑定上8889')
})

版本(服务端)

node聊天室

weChar

weChar

要求:


每个人有自己的昵称,在进入聊天室的时候自己输入。
每个人都可以发言

有一个区域用来展示所有的发言,并且要实时更新

有人加入的时候提示xxx加入了群聊

补加:群聊 私聊 加好友

了解长连接

用户和服务器的通信就只能是:用户发送请求 -> 服务器接受请求 -> 服务器返回结果 -> 用户收到结果。

➜  node-chat1 git:(master) ✗ node -v
v10.16.0
➜  node-chat1 git:(master) ✗ npm -v 
6.9.0

因为npm是国外的库可能有点慢,可以安装cnpm,执行下面命令
mac继续在终端输入:sudo npm install -g cnpm --registry=https://registry.npm.taobao.org

➜  test-js git:(master) ✗ cnpm -v
cnpm@6.1.0 (/usr/local/lib/node_modules/cnpm/lib/parse_argv.js)

linux乌班图
npm install -g cnpm --registry=https://registry.npm.taobao.org

然后输入
cnpm install --save express
等待安装成功,再安装
cnpm install --save socket.io
都安装成功之后我们就可以开始着手Coding了。

➜  test-js git:(master) ✗ node /Users/tianzi/Desktop/test-js/node-chat1/server.js
listening on *:3000


聊天室模型:

listening on *:3000



a user connected
a user connected
a user connected

---------------------------聊天内容
1 加入了群聊
2 加入了群聊
111
wocao
sdjj
dsadasd
dasdjajdsa
d
dskandjaskdjjdsajljkld;lkldall;kadkl;kl;dslkl;ks
saasd .
dsadjksajodas
hfjklsakjlfjjiojjfjijiofjjfjkjkfwjkfwjjojkjkkjjkjojpojkfwjojwjoojwjopjowjjowjopjopejojopvjopjopejojopjopjopjopjopjjopjjwopjwjopfjjfjwnfnwnlkfpjwjfpjowjfwp
5 加入了群聊

在server.js中写下以下代码:

用Nodejs搭建一个服务器。其中用到了express这个框架


【二】server.js 服务器接受消息

只需要两步:
监听前端的message事件
在监听到事件之后,将新消息广播给全体用户,这里也将广播事件的名字叫message吧。

 var app = require('express')(); //引入express库
var http = require('http').Server(app); //将express注册到http中

//当访问根目录时,返回Hello World
app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

//启动监听,监听3000端口
http.listen(3000, function(){
  console.log('listening on *:3000');
});

index.html

【一】index.html 将用户消息发送给服务器

用户输入消息,然后点击发送我们将用户的消息发送给服务器,然后服务器将消息广播给所有的用户。
我们需要给form的提交绑定一个事件,让它来处理新消息的发送。
【三】index.html 客户接受新消息

客户接收到服务器发来的message事件,将新消息呈现在面板中。

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>发送</button>
    </form>
  </body>
</html>

测试:

1. 开启服务器node server.js。
node /Users/tianzi/Desktop/test-js/node-chat1/server.js
listening on *:3000


2. 开一个标签(网页),输入地址localhost:3000,回车,填写昵称为1 。
http://localhost:3000/
或者127.0.0.1:3000
3. 再开一个标签,网页,填写昵称为2。

然后开始让两个人互相发送消息吧。
至此,聊天室以就做完了。

总结

用户a将自己的消息用message事件发送给服务器,服务器监听message事件接收其中的消息,将消息用事件message广播给全体用户,全体用户监听message事件,将事件接受到的消息呈现在聊天框中。PS:这一段是整个socket编程的核心,可以多读几遍细细理解。

node实现一个简单的登陆注册

用户注册:

1,输入用户名和密码,点击登陆 2,如果用户已注册提示用户已存在,第一次注册提示注册成功,其他不做验证

用户登陆:

1,输入用户名和密码,点击登陆 2,如果用户不存在做出相应提示,如果用户名或者密码输入错误做出相应提示,如果登陆成功,提示登陆成功

一、前端部分

在nodenote文件夹下创建www文件夹,用于存放user.html,因为需要交互所以额外引入一个ajax文件,创建一个index.js,用户写js逻辑代码 1,user.html代码

2,index.js注册部分

3.index.js登陆部分

二、后台部分

在nodenote文件夹下创建server.js 1,引入需要用到的模块,创建服务

2,接收数据完毕,在end中处理数据过程

这个时候你启动服务,输入localhost:8080,会报错,{ok:false,msg:’未知的act’}这是什么原因,原来是url有问题,我需要判断,可以打印处理url看一下,只有只想接口‘/user’的时候才能请求数据,而且页面用了ajax也需要用到服务环境,所以需要判断如果不是接口‘/user’,这个时候我应该在登陆页面,这里用到了fs的读取文件

通讯和协议

已知

学习node的基本东西:拆解难点:
1.在控制台输入东西
2.具备输入
3.接受端口------昨天解决,服务端的程序可以做出来。
4.定义协议,后面与百度的通讯

5.做一对一(客户端-服务器)聊天	process.stdin(过程).on
6.然后做一对多(一个客户端 -- 服务端/客户端) for循环sockSa[i]
7.

做一个curl 80端口

https://www.cnblogs.com/chenliyang/p/6558756.html
深入理解HTTP协议、HTTP协议原理分析


node提供环境。 浏览器提供环境。 dom是浏览器提供的。

\r\n的区别:

\r是回车,英文是Carriage return,表示使光标下移一格
\n是换行,英文是New line,表示使光标到行首
nodejs对\r的处理与在浏览器控制台对\r的处理不同,
在nodejs里
var str = 'a\rb';
console.log(str);  =>  b
在控制台里
var str = 'a\rb';
console.log(str);  =>  ab

官网node

//on 为事件 enevt
//方法 ()   ; 直接 用.
//属性 无括号;直接 用.


curl 模拟命令
curl -i www.baidu.com


短连接node定义一个长连接
login :name =xx
all:hello
@jack:aaaa
console.log(data.toString)

connection 连接

redis 就是非常高效
mysql就是二进制

socket.io 封装了太多
node 回调函数


net.createServer() section:
const net = require('net');
const client = net.createConnection({ port: 8124 }, () => {
  // 'connect' listener
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});


//面向百度编程永远入不了门,http协议


Net1.js

const net = require('net');
const server = net.createServer((sock) => {
    sock.write('world!\r\n');
    sock.end();
});

server.listen(8080, ()=>{
    console.log('server on 8080');
});

------------------------------------ net.createServer() 

const net = require('net');
const client = net.createConnection({ port: 8124 }, () => {
  //'connect' listener
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});

---------------------------------connections on port 8124
const net = require('net');
const server = net.createServer((c) => {
  // 'connection' listener
  console.log('client connected');
  c.on('end', () => {
    console.log('client disconnected');
  });
  c.write('hello\r\n');
  c.pipe(c);
});
server.on('error', (err) => {
  throw err;
});
server.listen(8124, () => {
  console.log('server bound');
});

----------------------- 服务器

const net = require('net');
const server = net.createServer(function (c) {
    console.log('连接')
    c.on('end',function(){
        console.log('断开')

    });
    c.on('data', (data) => {
        console.log(data.toString());
    })
    // c.write('hello a \r\n');
    c.write('b');

    // client.end();
});
server.on('error',(er) => {
    throw er;
});
server.listen(8889,()=>{
    console.log('bangding shang 8889')
})


http协议中connection头的作用

在http1.1中request和reponse header中都有可能出现一个connection的头,此header的含义是当client和server通信时对于长链接如何进行处理。 在http1.1中,client和server都是默认对方支持长链接的, 如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close;如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close. 不论request还是response的header中包含了值为close的connection,都表明当前正在使用的tcp链接在当天请求处理完毕后会被断掉。以后client再进行新的请求时就必须创建新的tcp链接了。

如何不痛苦:网络相关的东西。都是tcp+端口
socket:就是连接客户端和服务端的水管,连接 **定义常量 const-python**
# Filename:const.py
# 定义一个常量类实现常量的功能
# 
# 该类定义了一个方法__setattr()__,和一个异常ConstError, ConstError类继承 
# 自类TypeError. 通过调用类自带的字典__dict__, 判断定义的常量是否包含在字典 
# 中。如果字典中包含此变量,将抛出异常,否则,给新创建的常量赋值。 
# 最后两行代码的作用是把const类注册到sys.modules这个全局字典中。

class _const:
    class ConstError(TypeError):pass
    def __setattr__(self,name,value):
        if name in self.__dict__:
            raise self.ConstError("Can't rebind const (%s)" %name)
        self.__dict__[name]=value
        
const = _const()
const.PI=3.14
print(const.PI)

process.stdin过程

https://nodejs.org/dist/latest-v10.x/docs/api/process.html#process_process_stdout

process.stdin.setEncoding('utf8');
const net = require('net');
var client = new net.Socket();
client.on('data', (data) => {
    console.log(data.toString());
    // client.end();
});

client.on('end', () => {
    console.log('disconnected from server');
});
client.on('connect',()=>{

    console.log('fds')
    // client.write('GET / HTTP/1.1\n')
    // client.write('a')
    // client.write('dsd')
    // client.write('Host: 127.0.0.1\n\n')

    process.stdin.on('readable', () => {
        let chunk;
        // Use a loop to make sure we read all available data.
        while ((chunk = process.stdin.read()) !== null) {
            // process.stdout.write(`data: ${chunk}`);
            client.write(chunk)
        }
    });

});

client.connect(8889,'127.0.0.1')

---------------




var sockSa = []
const net = require('net');
const server = net.createServer(function (sock) {
    console.log('连接')
    sockSa.push(sock)

    console.log('这是所以sock:'+ sockSa.length)

  sock.on('end',function(){
        console.log('断开')

    });
    sock.on('data', (data) => {
        console.log(data.toString());
        for(var i= 0; i<sockSa.length ;i++){
            sockSa[i].write(data.toString())

        }

    })
    // c.write('hello a \r\n');
    // c.write('');

    // client.end();
});

server.on('error',(er) => {
    throw er;
});
server.listen(8889,()=>{
    console.log('bangding shang 8889')
})

node客户端/服务端

客户端啊
process.stdin.setEncoding('utf8'); //格式
const net = require('net');   //加载net的模块
var client = new net.Socket();   //客户端的socket

client.on('data', (data) => {     //net下socket的事件,data是变量
    console.log(data.toString());//收到服务器返回的数据
});

client.on('end', () => {
    console.log('退出聊天');
});

client.on('connect',()=>{
    console.log('连接成功!')
    process.stdin.on('readable', () => {
        let chunk;  //定义局部 变量
        
        while ((chunk = process.stdin.read()) !== null) {
            // if(chttps://www.runoob.com/nodejs/nodejs-net-module.html
            client.write(chunk)
            //死循环 就是你可以输入,我服务端可以接受
        }
    });
});

client.connect(8889,'127.0.0.1')

-------------
服务端啊 

var sockSa = []  //定义用户存放(地)点
const net = require('net');
const server = net.createServer(function (sock) {
    console.log('连接')
    sockSa.push(sock)   //把sock=客户端socket放在数组里面
    console.log('这是所有sock的个数:'+ sockSa.length)

    sock.on('end',function(){
        console.log('断开')
    });
    sock.on('data', (data) => {
        console.log(data.toString());  //在服务端显示,数据以字符串输出
        for(var i= 0; i<sockSa.length ;i++){
            if(sock==sockSa[i] ){
                continue;  //如果出现了指定的条件,然后继续循环中的下一个迭代。
            }else{
                sockSa[i].write(data.toString())
                //把接收到的数据分发给每个人。(广播功能)
            }
        }
    })
});
server.on('error',(er) => {
    throw er;           //对于报错不发
});
server.listen(8889,()=>{
    console.log('绑定上8889')
})

---------------------
  ---------------------------
//未完成版本


process.stdin.setEncoding('utf8'); //格式
const net = require('net');   //加载net的模块
var client = new net.Socket();   //客户端的socket
var isLogin = 0;   //登陆


client.on('data', (data) => {     //net下socket的事件,data是变量
    console.log(data.toString());//收到服务器返回的数据
    // client.write('')

});

client.on('end', () => {
    console.log('退出聊天');  //四次挥手
});


client.on('connect',()=>{
    console.log('连接成功,请在下面输入你的名字:')
        // 名字不可以以@开头;
        // 想发群聊必须加@,@所有人
        // 然后就是单聊,匹配名字进行聊天


    process.stdin.on('readable', () => {
        let chunk;  //定义局部 变量
         chunk = process.stdin.read()
        //输入in,标准输入,标准输出,错误输出
        while (chunk!== null) {
            client.write(chunk)   //读键盘
            //死循环 就是你可以输入,我服务端可以接受
            chunk = process.stdin.read()
        }
    });




});
client.connect(8889,'127.0.0.1')

-----------------


var sockSa = []  //定义用户存放(地)点
const net = require('net');
const server = net.createServer(function (sock) {
    console.log('连接')
    // sock.write('请输入:'+sock)
    // sock.log(sock)
    sockSa.push(sock)   //把sock=客户端socket放在数组里面
    console.log('这是所有sock的个数:'+ sockSa.length)

    sock.on('end',function(){
        console.log('断开')
    });
    sock.on('data', (data) => {

        let msg = data.toString();
        console.log(msg);  //在服务端显示,数据以字符串输出

        if (msg =='/@所有人+/'){



            for(var i= 0; i<sockSa.length ;i++){
                if(sock==sockSa[i] ){
                    continue;  //如果出现了指定的条件,然后继续循环中的下一个迭代。
                }else{
                    sockSa[i].write(msg)
                    //把接收到的数据分发给每个人。(广播功能)
                }
            }elseif(msg == '/@sockSa[i]'){

            }
        }
    })
});
server.on('error',(er) => {
    throw er;           //对于报错不发
});
server.listen(8889,()=>{
    console.log('绑定上8889')
})

  
  

客户端只可以输入

var sockServer = [];
const net  = require('net')
const server = net.createServer(function (sock){
    console.log('连接'); //net 帮我们做好了三次握手
    sock.on('end',function(){
        console.log('断开')
    })

    sock.on('data',(data)=>{
        data = data.toString()
        console.log(data)

    })

});

server.on('error',(er)=>{
    throw er;
})


server.listen(8889,()=>{
    console.log('绑定上了')
})


----------------------------------
const net =require('net')
var client = new net.Socket();

client.on('data',(data) => {
    console.log(data)
});

client.on('end',() =>{
    console.log('退出了')

})

client.on('connet',()=>{
    console.log('lian')
    process.stdio.on('readable',()=>{
        let chunk;//
        while ((chunk = process.stdio.read()) !== null){

            client.write(chunk)
        }

    })
})

client.connect(8889,'127.0.0.1')

tcp/ip学习总结

学会拆解问题最小化;

Socket --
连接
data

accept队列(运维大牛):阻塞掉; 找到socket
syn队列

c的训练 -- 数组不变。。
java --list 可以伸缩 扩容,成倍增长的。 php python
java数组不可以变


write 数据。。。on data

三次握手: (write)
客户端 找 服务端 商量个事;
服务端 说 可以的;   
客户端 那我们聊天吧;



js要熟;
connection  连接


四次挥手:(结束/end)
a不想给b说话了
b也不想给a说了
b要断开了
a也要断开了

css.div布局的训练;
字符串的操作,循环,if,正则



缺的东西
网络,
操作系统;
[]是可选参数

继续学习js

ejs模板引擎

1.使用之前

1.1安装

EJS 是后台模板,可以把我们数据库和文件读取的数据显示到 Html 页面上面(解析页面视图模板)。它是一个第三方模块,需要通过 npm 安装https://www.npmjs.com/package/ejs

npm  install ejs --save
cnpm install ejs --save

1.2引入

const  ejs = require('ejs');

2.怎么使用

ejs主要功能就是渲染html

//第一种用法
// 渲染字符串
ejs.render(str, data, [options]);
// => 输出绘制后的 HTML 字符串

//第二种用法
const template = ejs.compile(str, [options]);
template(data);
// => 输出绘制后的 HTML 字符串

//第三种用法
// 渲染文件
ejs.renderFile(filepath, data, [options], function(err, str){
    // str => 输出绘制后的 HTML 字符串
});

选项

  • cache 缓存编译后的函数,需要提供 filepath
  • filepath 被 cache 参数用做键值,同时也用于 include 语句
  • context 函数执行时的上下文环境
  • compileDebug 当为 false 时不编译调试语句
  • client 返回独立的编译后的函数
  • delimiter 放在角括号中的字符,用于标记标签的开与闭
  • debug 将生成的函数体输出
  • _with 是否使用 with() {} 结构。如果为 false,所有局部数据将存储在 locals 对象上。
  • localsName 如果不使用 with ,localsName 将作为存储局部变量的对象的名称。默认名称是 locals
  • rmWhitespace 删除所有可安全删除的空白字符,包括开始与结尾处的空格。对于所有标签来说,它提供了一个更安全版本的 -%> (在一行的中间并不会剔除标签后面的换行符)。
  • escape 为 <%= 结构设置对应的转义(escape)函数。它被用于输出结果以及在生成的客户端函数中通过 .toString() 输出。(默认转义 XML)。

3模板语法

3.1 分隔符(定界符)

开始标签(定界符)

  • <% ‘脚本’ 标签,用于流程控制,无输出。
  • <%= 输出数据到模板(输出是转义 HTML 标签)
  • <%- 输出非转义的数据到模板
  • <%# 注释标签,不执行、不输出内容

结束标签(定界符)

  • %> 一般结束标签

  • -%> 删除紧随其后的换行符

3.2 模板内使用JavaScript

<%= new Date() %>
<%= 1 + 100 %>
<%= nameList.join(',') %>

3.3 流程控制

<ul>
  <% users.forEach(function(user){ %>
    <%- include('user/show', {user: user}) %>
  <% }); %>
</ul>
<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>

3.4 Include

<ul>
  <% users.forEach(function(user){ %>
    <%- include('user/show', {user: user}) %>
  <% }); %>
</ul>
<%- include('header') -%>
<h1>
  Title
</h1>
<p>
  My page
</p>
<%- include('footer') -%>

3.5 自定义分隔符(定界符)

// 单个模板文件
ejs.render('<?= users.join(" | "); ?>', {users: users},
    {delimiter: '?'});


// 全局
ejs.delimiter = '$';
ejs.render('<$= users.join(" | "); $>', {users: users});


他山之石

node 官网
https://nodejs.org/dist/latest-v10.x/docs/api/net.html#net_net_createserver_options_connectionlistener

菜鸟
https://www.runoob.com/nodejs/nodejs-net-module.html

《http_百度百科》:
http://baike.baidu.com/view/9472.htm

《结果编码和http状态响应码》:
http://blog.tieniu1980.cn/archives/377

《使用Wireshark来检测一次HTTP连接过程》:
http://blog.163.com/wangbo_tester/blog/static/12806792120098174162288/

《http协议的几个重要概念》:
http://nc.mofcom.gov.cn/news/10819972.html

《http协议中connection头的作用》:
http://blog.csdn.net/barfoo/archive/2008/06/05/2514667.aspx 


打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦