nodejs中net模块TCP的使用

293 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

1、TCP的基本使用

服务器端:

主要分为三步:

1、引入net模块

2、创建服务器

3、绑定端口

// 1、 引入net模块
const net = require('net')
​
// 2、创建服务器
const server = net.createServer(client => {
    console.log('客户端已连接')
​
    client.on('end', () => {
        console.log('客户端断开连接')
    })
    client.on('data',(data)=>{
        console.log(data.toString())
    })
    client.write('客户端你好')
})
​
server.on('error', (err) => {
    console.log(err)
});
​
​
// 3、绑定端口
server.listen(8080, () => {
    console.log('服务器启动成功')
})

客户端:

分为四步:

1、引入net模块

2、创建客户端并连接服务器

3、对服务器端发过来的信息进行监听

// 1、引入net模块
const net = require('net')
​
​
// 2、连接服务器
const client = net.createConnection({ port: 8080 }, () => {
    console.log('服务器连接成功')
    //给服务器发送消息消息
    //client.write('服务器你好')
​
    process.stdin.on('data', data => {
        client.write(data.toString().trim())
    })
​
    // 4、断开连接
    client.on('end', () => {
        console.log('与服务器断开连接...')
    })
})
​
// 3、监听服务器发过来的消息
client.on('data', (data) => {
    console.log('服务器发过来的消息: ', data.toString())
})
​

2、聊天室案例

使用TCP服务,创建一个简单的聊天室,其中包含登录功能,私聊功能以及群发功能

服务器端:

// 1、 引入net模块
const net = require('net')
const types=require('./types')
​
​
const users=[]
// 2、创建服务器
const server = net.createServer(client => {
    
    
    client.on('end', () => {
        
    })
    client.on('error',()=>{
        //用户离线
        const pos =users.findIndex(user=>user===client)
        users.splice(pos,1)//删除
        // console.log('users',users)
        users.forEach(u =>{
            // console.log('name',u.username)
            u.write(JSON.stringify({
                type:types.logout,
                username:client.username,
                length:users.length
            }))
        })
    })
​
​
    client.on('data',(data)=>{
        // users.forEach(user=>{
        //     user.write(data.toString())
        // })
        data=JSON.parse(data.toString())
        // console.log(data)
        type = data.type
        switch (type) {
            case types.login:
                // 登录操作
                const user = users.find(user=>{
                    return user.username===data.username
                })
                if(user){
                    // 用户名已存在
                    client.write(JSON.stringify({
                        type:types.login,
                        success:false,
                    }))
                }else{
                    client.username=data.username
                    users.push(client)
                    client.write(JSON.stringify({
                        type:types.login,
                        success:true,
                        username:data.username,
                        length:users.length
                    }))
                }
                break;
            case types.p2p:
                //私聊操作
                const u = users.find(user=>{
                    return user.username===data.username
                })
                u.write(JSON.stringify({
                    type:types.p2p,
                    username:client.username,
                    message:data.message
                }))
                break;
​
            case types.broadcast:
                //群发操作
                users.forEach(user=>{
                    if(user!==client){
                        console.log('server 群发')
                        user.write(JSON.stringify({
                            type:types.broadcast,
                            message:data.message,
                            username:client.username
                        }))
                    }
                })
                break;
            default:
                break;
        }
    })
    
})
​
server.on('error', (err) => {
    console.log(err)
});
​
​
​
// 3、绑定端口
server.listen(8080, () => {
    console.log('服务器启动成功')
})

客户端:

// 1、引入net模块
const net = require('net')
const types = require('./types')
​
let username=""
// 2、连接服务器
const client = net.createConnection({ port: 8080 }, () => {
    console.log('服务器连接成功')
    console.log('请输入用户名:')
​
    process.stdin.on('data', data => {
        data = data.toString().trim()
        if(username===""){
            // 登录操作
            // console.log('username',username)
            // console.log('data',data)
​
            client.write(JSON.stringify({
                type:types.login,
                username:data
            }))
            return
        }else{
            // 聊天操作
            const matches = /^@(\w+)\s(.+)$/.exec(data)
            if (matches) { // 如果本次的消息符合 @xxx xxx 格式
                return client.write(JSON.stringify({
                    type: types.p2p,
                    username: matches[1],
                    message: matches[2]
                }))
            }else{
                //群发操作
                console.log('群发操作')
                client.write(JSON.stringify({
                    type:types.broadcast,
                    message:data
                }))
                return
            }
        }
        
    })
})
​
// 3、监听服务器发过来的消息
client.on('data', (data) => {
    // console.log('服务器发过来的消息: ', data.toString())
    data=JSON.parse(data.toString())
    const type = data.type
    // console.log(data)
    switch (type) {
        case types.login:
            // 登录相关,判断用户名是否重复
            if(data.success){
                console.log(`登录成功,当前有${data.length}人在线`)
                username=data.username
            }else{
                console.log('用户名已存在,请重新输入:')
            }
            break;
        case types.p2p:
            //有人私聊
            console.log(`${data.username}对你说:${data.message}`)
            break;
        case types.broadcast:
            //群发消息
            console.log(`${data.username}说:${data.message}`)
            break
        case types.logout:
            //有人下线
            console.log(`${data.username}已下线,当前还有${data.length}人在线`)
            break;
        default:
            break;
    }
})
​
​

type.js模块

module.exports = {
  login: 0,
  broadcast: 1,
  p2p: 2,
  logout: 3
}