tcp笔记

187 阅读1分钟

telnet

let net = require('net')
let port = 3000

// let server = net.createServer(function(socket){
//     console.log('客户端连接了服务端')
// })
let server = net.createServer()
server.on('connection',(socket)=>{  // socket套接字 是一个Duplex双工流
    console.log(`客户端连接了服务端`)
    //可写流操作
    socket.write('hello tcp')
    //socket.end()  // 服务端关闭,客户端会断开

    //可读流操作
    socket.setEncoding('utf8')  // 设置字符编码
    socket.on('data',(data)=>{ //接收客户端数据
        console.log(data) // data.toString()
        server.close() //关闭服务器,但是已经连接的客户端不会断掉,只是不接受新的请求。当最后一个客户端连接断掉会,会触发close监听事件
        //server.unref() //也表示关闭,与close区别是可以继续接收新的请求,当没有客户端连接时会自动关闭服务,不触发close监听事件
    })
})

//server.maxConnections = 2  // 设置最大客户端连接数
server.on('error',(err)=>{
    if(err.code==='EADDRINUSE'){  // 端口被占用
        server.listen(port,function(){
            console.log(`server start ${++port}`)
        })
    }
})
server.listen(port,function(){
    console.log(`server start ${port}`)
})
server.on('close',()=>{
    console.log('关闭服务器,会触发我')
})

模拟http的实现

let net = require('net');
let server = net.createServer();
function parserHeader(h) {
  let obj = {};
  let headers = h.split(/\r\n/);
  let line = headers.shift();
  let [method,path,version] = line.split(' ');
  let head = {}
  headers.forEach(line => {
    let [key,value] = line.split(': ');
    head[key] = value;
  });
  obj['method'] = method;
  obj['path'] = path;
  obj['version'] = version;
  obj['headers'] = head
  return obj
}
let {Readable} = require('stream');
class IncomingMessage extends Readable{
  _read(){}
}
function parser(socket,callback) {
  let im = new IncomingMessage
  function fn() {
    let result = socket.read().toString();
    let [head,content ]  = result.split(/\r\n\r\n/);
    let obj = parserHeader(head);
    // readable方法会触发多次,触发一次后就移除掉
    socket.removeListener('readable',fn);
    // 就是把请求体的部分再塞回到可读流生成
    Object.assign(im,obj);
    im.push(content);
    im.push(null);
    callback(im,socket);
  }
  socket.on('readable',fn);
}
server.on('connection',function (socket) {
    parser(socket,function (req,res) {
      server.emit('request',req,res);
    })
});
server.on('request',function (req,res) {
  console.log(req.method);
  console.log(req.headers);
  req.on('data',function (data) {
    console.log(data.toString());
  });
  req.on('end',function () {
    console.log('ok完毕');
    res.end(`
HTTP/1.1 200 ok
Content-Length: 2

ok
    `)
  })
});
server.listen(3000);