const net = require('net')
const server = net.createServer()
server.on('connection',clientSocket=>{
console.log('连接成功')
// 通过clientSocket 给当前连接的客户端发送数据
clientSocket.write('Connection successful!')
})
server.listen(3000,()=>{
console.log('Server running 127.0.0.1 3000')
})
const net = require('net')
const client = net.createConnection({
host:'127.0.0.1',
port:3000
})
client.on('connect',()=>{
console.log('成功连接到服务器了')
})
// 客户端接收服务端返回的数据
client.on('data',data =>{
console.log(data.toString())
})
运行代码(先运行服务端后运行客户端,否则会报错)
文件夹路径>nodemon 文件夹名称
服务端打印如下:
客户端打印如下:
注意:运行nodemon前提是已经全局安装,如遇到下面的情况,说明没有安装。
nodemon : 无法将“nodemon”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路
径正确,然后再试一次。
所在位置 行:1 字符: 1
+ nodemon --version
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (nodemon:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
解决方法:安装全局的nodemon,在终端执行
npm install -g nodemon
const net = require('net')
const server = net.createServer()
server.on('connection', clientSocket => {
console.log('客户端连接成功')
// 监听clientSocket的data事件
clientSocket.on('data', data => {
console.log('客户端:', data.toString())
})
// 给客户端发送消息
// 通过clientSocket 给当前连接的客户端发送数据
clientSocket.write('我是服务端')
})
server.listen(3000, () => {
console.log('Server running 127.0.0.1 3000')
})
const net = require('net')
const client = net.createConnection({
host: '127.0.0.1',
port: 3000
})
client.on('connect', () => {
console.log('服务端连接成功')
// 当客户端与服务器连接成功后,客户端就可以给服务端发送消息
client.write('我是客户端')
})
// 客户端监听data事件
// 客户端接收服务端返回的数据 当服务端发消息过来就会触发改事件
client.on('data', data => {
console.log('服务端:', data.toString())
})
const net = require('net')
const client = net.createConnection({
host: '127.0.0.1',
port: 3000
})
client.on('connect', () => {
console.log('服务端连接成功')
// 当客户端与服务器连接成功后,客户端就可以给服务端发送消息
client.write('我是客户端')
// 当客户端与服务端建立连接成功后,我们可以监听终端的输入
// 将获取终端的输入发送给服务端
process.stdin.on('data',data=>{
// .trim() 去除回车打印显示的空格
// console.log(data.toString().trim())
client.write(data.toString().trim())
})
})
// 客户端监听data事件
// 客户端接收服务端返回的数据 当服务端发消息过来就会触发改事件
client.on('data', data => {
console.log('服务端:', data.toString())
})
运行代码结果如下(前提是服务端和客户端连接成功,否则会报错)
数据格式设计(语言协议)
const net = require('net')
const server = net.createServer()
const clients = []
server.on('connection',clientSocket=>{
// 把当前连接的客户端通信接口存储到数据中
clients.push(clientSocket)
clientSocket.on('data',data=>{
console.log('有人说',data.toString())
//把数据发送给所有的客户端
clients.forEach(socket=>{
if (socket !== clientSocket) {
socket.write(data)
}
})
})
clientSocket.write("我是服务端")
})
server.listen(3000,()=>{
console.log('Server running 127.0.0.1 3000')
})
const net = require('net')
const client = net.createConnection({
host:'127.0.0.1',
port:3000
})
client.on('connect',()=>{
console.log('客户端与服务端连接成功')
process.stdin.on('data',data=>{
data = data.toString().trim()
client.write(data)
})
client.write('我是客户端')
})
client.on('data',data=>{
console.log(data.toString())
})
用户登录数据格式要求如下:
客户端:
{
"type": "login",
"nickName": "xxx"
}
服务端:
{
"type": "login",
"success": true | false,
"message": "登录成功|失败",
"sumUsers": 10
}
module.exports = {
login:0,
broadcast:1,
p2p:2
}
const net = require("net");
const types = require("./types");
const server = net.createServer();
//[Socket,Socket,Socket...]用于存储客户端昵称
const users = [];
server.on("connection", clientSocket => {
clientSocket.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (users.find(item => item.nickName === data.nickName)) {
return clientSocket.write(
JSON.stringify({
type: types.login,
success: false,
message: "昵称已重复"
})
);
}
clientSocket.nickName = data.nickName;
users.push(clientSocket);
clientSocket.write(
JSON.stringify({
type: types.login,
success: true,
message: "登录成功",
nickName: data.nickName,
sumUsers: users.length
})
);
break;
case types.broadcast:
break;
case types.p2p:
break;
default:
break;
}
});
});
server.listen(3000, () => {
console.log("Server running 127.0.0.1 3000");
});
const net = require("net");
const types = require("./types");
let nickName = null;
const client = net.createConnection({
host: "127.0.0.1",
port: 3000
});
client.on("connect", () => {
console.log("客户端与服务端连接成功");
process.stdout.write("请输入昵称:");
process.stdin.on("data", data => {
// .trim() 去除回车打印显示的空格
data = data.toString().trim();
if (!nickName) {
// write()方法不能直接发送对象,只能发送二进制数据和字符串,所有这里需要转换成字符串发送
client.write(
JSON.stringify({
type: types.login,
nickName: data
})
);
}
});
});
// 客户端监听data事件
// 客户端接收服务端返回的数据 当服务端发消息过来就会触发改事件
client.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (!data.success) {
console.log(`登录失败:${data.message}`);
process.stdout.write("请输入昵称:");
} else {
console.log(`登录成功,当前在线用户:${data.sumUsers}`);
nickName = data.nickName;
}
break;
case types.broadcast:
break;
case types.p2p:
break;
default:
break;
}
});
广播消息数据格式要求如下:
客户端:
{
"type": "broadcast",
"message": "xxx"
}
服务端:
{
"type": "broadcast",
"nickname": "xxx",
"message": "xxx"
}
const net = require("net");
const types = require("./types");
const server = net.createServer();
//[Socket,Socket,Socket...]用于存储客户端昵称
const users = [];
server.on("connection", clientSocket => {
clientSocket.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (users.find(item => item.nickName === data.nickName)) {
return clientSocket.write(
JSON.stringify({
type: types.login,
success: false,
message: "昵称已重复"
})
);
}
clientSocket.nickName = data.nickName;
users.push(clientSocket);
clientSocket.write(
JSON.stringify({
type: types.login,
success: true,
message: "登录成功",
nickName: data.nickName,
sumUsers: users.length
})
);
break;
case types.broadcast:
users.forEach(item => {
item.write(
JSON.stringify({
type: types.broadcast,
nickName: clientSocket.nickName,
message: data.message
})
);
});
break;
case types.p2p:
break;
default:
break;
}
});
});
server.listen(3000, () => {
console.log("Server running 127.0.0.1 3000");
});
const net = require("net");
const types = require("./types");
let nickName = null;
const client = net.createConnection({
host: "127.0.0.1",
port: 3000
});
client.on("connect", () => {
console.log("客户端与服务端连接成功");
process.stdout.write("请输入昵称:");
process.stdin.on("data", data => {
// .trim() 去除回车打印显示的空格
data = data.toString().trim();
if (!nickName) {
// write()方法不能直接发送对象,只能发送二进制数据和字符串,所有这里需要转换成字符串发送
return client.write(
JSON.stringify({
type: types.login,
nickName: data
})
);
}
//群聊
client.write(
JSON.stringify({
type: types.broadcast,
message: data
})
);
});
});
// 客户端监听data事件
// 客户端接收服务端返回的数据 当服务端发消息过来就会触发改事件
client.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (!data.success) {
console.log(`登录失败:${data.message}`);
process.stdout.write("请输入昵称:");
} else {
console.log(`登录成功,当前在线用户:${data.sumUsers}`);
nickName = data.nickName;
}
break;
case types.broadcast:
console.log(`${data.nickName}:${data.message}`);
break;
case types.p2p:
break;
default:
break;
}
});
点对点消息数据格式要求如下:
客户端:
{
"type": "p2p",
"to": "xxx",
"message": "xxx"
}
服务端:
{
"type": "p2p",
"from": "xxx",
"to": "xxx",
"message": "xxx"
}
const net = require("net");
const types = require("./types");
const server = net.createServer();
//[Socket,Socket,Socket...]用于存储客户端昵称
const users = [];
server.on("connection", clientSocket => {
clientSocket.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (users.find(item => item.nickName === data.nickName)) {
return clientSocket.write(
JSON.stringify({
type: types.login,
success: false,
message: "昵称已重复"
})
);
}
clientSocket.nickName = data.nickName;
users.push(clientSocket);
clientSocket.write(
JSON.stringify({
type: types.login,
success: true,
message: "登录成功",
nickName: data.nickName,
sumUsers: users.length
})
);
break;
case types.broadcast:
users.forEach(item => {
item.write(
JSON.stringify({
type: types.broadcast,
nickName: clientSocket.nickName,
message: data.message
})
);
});
break;
case types.p2p:
console.log(data);
const user = users.find(item => item.nickName === data.nickName);
if (!user) {
return clientSocket.write(
JSON.stringify({
type: types.p2p,
success: false,
message: "该用户不存在"
})
);
}
user.write(
JSON.stringify({
type: types.p2p,
success: true,
nickName: clientSocket.nickName,
message: data.message
})
);
break;
default:
break;
}
});
});
server.listen(3000, () => {
console.log("Server running 127.0.0.1 3000");
});
const net = require("net");
const types = require("./types");
let nickName = null;
const client = net.createConnection({
host: "127.0.0.1",
port: 3000
});
client.on("connect", () => {
console.log("客户端与服务端连接成功");
process.stdout.write("请输入昵称:");
process.stdin.on("data", data => {
// .trim() 去除回车打印显示的空格
data = data.toString().trim();
if (!nickName) {
// write()方法不能直接发送对象,只能发送二进制数据和字符串,所有这里需要转换成字符串发送
return client.write(
JSON.stringify({
type: types.login,
nickName: data
})
);
}
// 私聊
const matches = /^@(\w+)\s(.+)$/.exec(data);
if (matches) {
//如果本次的消息符合 @昵称 xxx(消息内容)格式
return client.write(
JSON.stringify({
type: types.p2p,
nickName: matches[1],
message: matches[2]
})
);
}
//群聊
client.write(
JSON.stringify({
type: types.broadcast,
message: data
})
);
});
});
// 客户端监听data事件
// 客户端接收服务端返回的数据 当服务端发消息过来就会触发改事件
client.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (!data.success) {
console.log(`登录失败:${data.message}`);
process.stdout.write("请输入昵称:");
} else {
console.log(`登录成功,当前在线用户:${data.sumUsers}`);
nickName = data.nickName;
}
break;
case types.broadcast:
console.log(`${data.nickName}:${data.message}`);
break;
case types.p2p:
if (!data.success) {
return console.log(`发送失败:${data.message}`);
}
console.log(`${data.nickName}对你说:${data.message}`);
break;
default:
break;
}
});
上线|离线通知日志数据格式要求如下:
服务端:
{
"type": "log",
"message": "xxx 进入|离开了聊天室,当前在线人数:xx"
}
module.exports = {
login:0,
broadcast:1,
p2p:2,
login:3
}
const net = require("net");
const types = require("./types");
const server = net.createServer();
//[Socket,Socket,Socket...]用于存储客户端昵称
const users = [];
server.on("connection", clientSocket => {
clientSocket.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (users.find(item => item.nickName === data.nickName)) {
return clientSocket.write(
JSON.stringify({
type: types.login,
success: false,
message: "昵称已重复"
})
);
}
clientSocket.nickName = data.nickName;
users.push(clientSocket);
clientSocket.write(
JSON.stringify({
type: types.login,
success: true,
message: "登录成功",
nickName: data.nickName,
sumUsers: users.length
})
);
users.forEach(user => {
if (user !== clientSocket) {
user.write(
JSON.stringify({
type: types.login,
message: `${data.nickName}进入了聊天室,当前在线用户:${
users.length
}`
})
);
}
});
break;
case types.broadcast:
users.forEach(item => {
item.write(
JSON.stringify({
type: types.broadcast,
nickName: clientSocket.nickName,
message: data.message
})
);
});
break;
case types.p2p:
console.log(data);
const user = users.find(item => item.nickName === data.nickName);
if (!user) {
return clientSocket.write(
JSON.stringify({
type: types.p2p,
success: false,
message: "该用户不存在"
})
);
}
user.write(
JSON.stringify({
type: types.p2p,
success: true,
nickName: clientSocket.nickName,
message: data.message
})
);
break;
default:
break;
}
});
clientSocket.on("end", () => {
const index = users.findIndex(
user => user.nickName === clientSocket.nickName
);
if (index !== -1) {
const offlineUser = users[index];
users.splice(index, -1);
//广播通知其他用户,xxx用户已离开,当前剩余人数:xxx
users.forEach(user => {
user.write(
JSON.stringify({
type: types.login,
message: `${offlineUser.nickname} 离开了聊天室,当前在线用户:${
users.length
}`
})
);
});
}
});
});
server.listen(3000, () => {
console.log("Server running 127.0.0.1 3000");
});
const net = require("net");
const types = require("./types");
let nickName = null;
const client = net.createConnection({
host: "127.0.0.1",
port: 3000
});
client.on("connect", () => {
console.log("客户端与服务端连接成功");
process.stdout.write("请输入昵称:");
process.stdin.on("data", data => {
// .trim() 去除回车打印显示的空格
data = data.toString().trim();
if (!nickName) {
// write()方法不能直接发送对象,只能发送二进制数据和字符串,所有这里需要转换成字符串发送
return client.write(
JSON.stringify({
type: types.login,
nickName: data
})
);
}
// 私聊
const matches = /^@(\w+)\s(.+)$/.exec(data);
if (matches) {
//如果本次的消息符合 @昵称 xxx(消息内容)格式
return client.write(
JSON.stringify({
type: types.p2p,
nickName: matches[1],
message: matches[2]
})
);
}
//群聊
client.write(
JSON.stringify({
type: types.broadcast,
message: data
})
);
});
});
// 客户端监听data事件
// 客户端接收服务端返回的数据 当服务端发消息过来就会触发改事件
client.on("data", data => {
data = JSON.parse(data.toString().trim());
switch (data.type) {
case types.login:
if (!data.success) {
console.log(`登录失败:${data.message}`);
process.stdout.write("请输入昵称:");
} else {
console.log(`登录成功,当前在线用户:${data.sumUsers}`);
nickName = data.nickName;
}
break;
case types.broadcast:
console.log(`${data.nickName}:${data.message}`);
break;
case types.p2p:
if (!data.success) {
return console.log(`发送失败:${data.message}`);
}
console.log(`${data.nickName}对你说:${data.message}`);
break;
case login:
console.log(data.message);
break;
default:
break;
}
});
运行代码结果如下:(下线时显示报错,暂未找到原因,后续再处理)
{
"type": "xxx"
}