Nodejs Socket+TCP,实现小小简单聊天程序

Nodejs Socket+TCP,实现小小简单聊天程序

这几天开始抱着两本书重头学习Node,最近也不知自己在瞎忙什么,算了,进入正题吧!
在Node中使用Socket编程,总的给我一个感觉就是爽!今天完成了一个极为简单的基于控制台模式的聊天小程序
之所以写这个就是为了学习下基于Node的Socket编程,协议就是如标题的TCP协议了

#####实现内容#####

就是一个server,和(n+)个Client,server端监视client的连接状态。并且实现broadcast,其形式
也就是相当于一个聊天大厅或者QQ群的形式,只要有客户端成功连接,就会立即加入当前的聊天
状态。当然了我这个小小的应用就是简单的实现,并没有考虑到数据存储的功能,you can do it :)
还有一些 问题待解决。先上代码吧, ###server端:###

var sockets = []; //Collecting all the clients and broadcast the user data to everyone
var server = require('net').createServer(function(socket) {
console.log('new connection');
//socket.setKeepAlive(true);
sockets.push(socket); //if have new connection sockets elements +1
socket.setEncoding('utf8');
socket.on('data', function(data) {
  //进行广播,是每个客户端收到消息
  sockets.forEach(function(otherSocket) {
    if (otherSocket !== socket) {
      otherSocket.write(data + "\n");
    }
  });
});
socket.on('end', function() {
  console.log('client connection ended!');
});
socket.on('close', function() {
  console.log('connection closed');
  var index = sockets.indexOf(socket); //如果一个Client下线退出,清除相关信息
  sockets.splice(index, 1);
});
}).listen(4006, function() {
console.log('waiting for client connection···');
address = server.address(); //这里有一点需要注意,server.address()一定要在listening事件触发后!
console.log('opended server on %j', address);
}).on('close', function() {
console.log('server closed!');
}).on('error', function(err) {
console.log('Server error:' + err.message);
});

###client端###

var net = require('net'),
  definePort = 4006,
  quitting = false,
  retryTimeout = 3000,
  retriedTimes = 0,
  maxRetries = 10,
  client,
  myName = "";

process.stdin.resume();

process.stdin.on(‘data’, function(data) { if (data.toString().trim().toLowerCase() === ‘quit’) { quitting = true; console.log(‘quitting···’); client.end(); process.stdin.pause(); } else { if (myName !== “”) { client.write(myName + “:” + data); } else { myName = data; return false; } } }); (function connect() { function reconnect() { if (retriedTimes >= maxRetries) { throw new Error(‘最大尝试次数已到,请检查网络!’); } else { retriedTimes += 1; setTimeout(connect, retryTimeout); } } client = net.connect({ port: definePort, }, function() { client.setEncoding(‘utf8’); retriedTimes = 0; //这边就是当连接上就重置retriedTimes console.log(’==========================\nconnected to server.\n键入 quit 退出当前聊天模 式.\n==========================’); console.log(‘★★★★★★★★★★★★★\n进入聊天时第一件事是:\n键入自己的昵称\n★★★★★★★★★★★★★\n您的昵称:’) }).on(‘data’, function(data) { //console.log(data.toString()); }).on(‘end’, function() { console.log(‘client disconnected!’); }).on(‘error’, function(err) { console.log(‘client error:’ + err.message); }).on(‘close’, function() { if (!quitting) { console.log(‘connection got closed,will try to reconnect’); reconnect(); } }); client.pipe(process.stdout, { end: false }); }());

####问题####

  • 一个就是显示,总觉得显示格式的不太给力
  • 第二就是可能是编码的问题,字母发送显示是正常的,而汉字出现乱码,或者是不显示。我开始设置了 client.setEncoding('utf8'); 但是没效果,★★★希望得到解答★★★
  • 本人也是刚刚入门学习,代码有不对的地方,各位请雅正:)
  • 参考:《professional node.js》

5 回复

好的,下面是关于如何使用 Node.js 实现一个简单的 TCP 聊天程序的详细内容,包括服务器端和客户端的代码。

Node.js Socket+TCP,实现小小简单聊天程序

这段时间我在重新学习 Node.js,今天我完成了一个基于控制台模式的聊天小程序。这个程序主要用到了 Node.js 的 net 模块来实现 TCP 通信。让我们一起来看看具体的实现过程吧!

实现内容

该聊天程序包含一个服务器和多个客户端。服务器会监视所有客户端的连接状态,并实现广播功能。具体来说,只要有一个客户端连接成功,它就会立即加入当前的聊天状态。这个应用虽然简单,但足以展示基本的 TCP 通信原理。

服务器端代码

var sockets = []; // 存储所有客户端连接

var server = require('net').createServer(function(socket) {
  console.log('new connection');
  
  sockets.push(socket); // 新连接时,将 socket 添加到数组中
  
  socket.setEncoding('utf8'); // 设置编码为 UTF-8
  
  socket.on('data', function(data) {
    // 广播数据给其他所有客户端
    sockets.forEach(function(otherSocket) {
      if (otherSocket !== socket) {
        otherSocket.write(data + "\n");
      }
    });
  });

  socket.on('end', function() {
    console.log('client connection ended!');
  });

  socket.on('close', function() {
    console.log('connection closed');
    var index = sockets.indexOf(socket); // 找到并移除关闭的 socket
    sockets.splice(index, 1);
  });
});

server.listen(4006, function() {
  console.log('waiting for client connection···');
  var address = server.address();
  console.log('opened server on %j', address);
}).on('close', function() {
  console.log('server closed!');
}).on('error', function(err) {
  console.log('Server error:' + err.message);
});

客户端代码

var net = require('net');
var definePort = 4006;
var quitting = false;
var retryTimeout = 3000;
var retriedTimes = 0;
var maxRetries = 10;
var client;
var myName = "";

process.stdin.resume();

process.stdin.on('data', function(data) {
  if (data.toString().trim().toLowerCase() === 'quit') {
    quitting = true;
    console.log('quitting···');
    client.end();
    process.stdin.pause();
  } else {
    if (myName !== "") {
      client.write(myName + ":" + data);
    } else {
      myName = data.trim();
      console.log('Your nickname is set as:', myName);
      return false;
    }
  }
});

(function connect() {
  function reconnect() {
    if (retriedTimes >= maxRetries) {
      throw new Error('Maximum retries reached. Please check your network.');
    } else {
      retriedTimes += 1;
      setTimeout(connect, retryTimeout);
    }
  }

  client = net.connect({ port: definePort }, function() {
    client.setEncoding('utf8');
    retriedTimes = 0;
    console.log('Connected to server.');
    console.log('Type "quit" to exit the chat mode.');
    console.log('Please enter your nickname:');
  }).on('data', function(data) {
    console.log(data.toString());
  }).on('end', function() {
    console.log('Disconnected from server!');
  }).on('error', function(err) {
    console.log('Client error:', err.message);
  }).on('close', function() {
    if (!quitting) {
      console.log('Connection closed, will try to reconnect.');
      reconnect();
    }
  });

  client.pipe(process.stdout, { end: false });
}());

问题及解决方案

  1. 显示格式问题

    • 可以通过在 console.log 中添加更多的格式化信息来改善显示格式。
  2. 中文乱码问题

    • 确保客户端和服务端都设置了正确的编码(如 UTF-8)。在本示例中,我们已经设置了 setEncoding('utf8'),所以应该不会有乱码问题。如果仍然存在乱码,可以尝试检查系统环境变量是否正确设置为 UTF-8 编码。

希望这些代码和解释能帮助你更好地理解如何使用 Node.js 实现一个简单的聊天程序。如果有任何问题或需要进一步的帮助,请随时提问!


它这个格式怎么显示的参差不齐啊!我原先的代码缩进都是挺好的。这样的缩进看得不爽啊!

这个还真不是 CNode 代码问题, 楼主缩进里混用了 Tab 和空格造成的… 已编辑…

看吧不统一缩进一不小心就出问题了…

请问楼主,汉字乱码的问题解决了吗?

为了实现一个基于Node.js的简单聊天程序,我们可以使用TCP协议来创建服务器和客户端。以下是详细的实现步骤和代码示例:

服务器端代码

服务器负责监听连接请求,并将所有客户端的数据广播给其他客户端。

var net = require('net');

var sockets = [];

var server = net.createServer(function(socket) {
  console.log('new connection');
  
  sockets.push(socket);
  
  socket.setEncoding('utf8');
  
  socket.on('data', function(data) {
    sockets.forEach(function(otherSocket) {
      if (otherSocket !== socket) {
        otherSocket.write(data);
      }
    });
  });

  socket.on('end', function() {
    console.log('client connection ended!');
  });

  socket.on('close', function() {
    console.log('connection closed');
    var index = sockets.indexOf(socket);
    sockets.splice(index, 1);
  });
});

server.listen(4006, function() {
  console.log('server listening on port 4006');
});

客户端代码

客户端负责连接到服务器,并发送和接收消息。

var net = require('net');

var client = new net.Socket();
client.connect(4006, 'localhost', function() {
  console.log('Connected to server');
  client.write('Enter your nickname:');
});

client.on('data', function(data) {
  console.log(data.toString());
});

client.on('close', function() {
  console.log('Connection closed');
});

process.stdin.on('data', function(data) {
  var message = data.toString().trim();
  if (message.toLowerCase() === 'quit') {
    client.destroy();
  } else {
    client.write(message);
  }
});

说明

  1. 服务器端

    • 使用net.createServer()创建一个TCP服务器。
    • 监听连接事件,并将每个新连接的socket添加到sockets数组中。
    • 处理data事件,将接收到的数据广播给所有其他客户端。
    • 处理endclose事件,移除断开连接的socket。
  2. 客户端

    • 使用net.Socket()创建一个TCP客户端。
    • 连接到服务器,并监听data事件以接收消息。
    • 处理stdin输入,将用户输入的消息发送到服务器。
    • 处理close事件,在连接关闭时重新连接。

通过以上代码,你可以实现一个简单的聊天室应用,支持多个客户端同时连接并互相通信。

回到顶部