tcp不能通过浏览器访问,因为他并不知道协议的特点,如果用windows开发,需要安装'PuTTY,xsel',mac不需要
tcp属于传输层 => 数据传递 ,传输层有很多协议类似于udp等

我们最常用的http属于应用层,tcp属于传输层,也就是说应用层建立在传输层上,在node中为了专门实现某种传输手段,提供了一个tcp包
windows需要安装telnet 控制面板=>程序 => telnet√一下 Telnet localhost 3000(不建议)
Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。
我们用putty (支持中文)

安装后需要配置常用端口.
//node实现tcp协议 给我们提供了一个包 net模块
//tcp 交互也要有服务端和客户端
//客户端: 可以通过任意一个端口号给服务发请求
//服务端:接受并且响应
let net = require('net');
//创建服务端
//socket套接字 会话,http有请求和响应
// let server = net.createServer(function(socket){
// //请求到来的时候执行以下
// console.log('客户端链接了服务端');
// })
//等同于
let server = net.createServer();
server.on('connection',function(socket){
//请求到来的时候执行以下
console.log('客户端链接了服务端');
})
// (端口号,服务器地址默认不写,511(可以接收多少个请求))
//监听成功会自动走回调
let port = 3000;
server.listen(port,function(){
console.log(`server start ${port}`);
})
我们在服务端建立端口,同时在cmd上运行,会报错

这个我们最常见的端口冲突,我们想在端口冲突的时候让端口自增1
我们加一行代码就可以解决
server.on('error',function(err){
if(err.code == 'EADDRINUSE'){
server.listen(++port)
}
})
//设置最大连接数
server.maxConnections = 2
socket 是一个Duplex 就是双攻流,可读可写 即客户端一个,服务端一个,两个是同一个人,
server.on('connection',function(socket){
//请求到来的时候执行以下
socket.write("欢迎光临")
})
设置当客户端请求时候回应如图

socket.end();//关闭客户端
server.close();//关闭自己 如果触发了close事件就不会在触发新的请求了
server.unref(); //表示关闭 没有客户端链接会自己关闭,不会触发close事件
//接收消息,可以通过流的方式接收到数据
socket.setEncoding('utf8')
socket.on('data' , function(data){
console.log(data)
});

现在我们来实现一个聊天室, 每次链接服务端socket不是同一个人
- 提示当前在线人数多少,总共能容纳多少人
- 提示请输入用户名
- 广播消息
//创建一个服务
let net = require('net');
let server = net.createServer();
//client存储用户信息
let client = {};
//每次链接服务器 socket每次都会产生新的
server.on('connection',function(socket){
//设置最大连接数,server.getConnections每次连接返回给客户端信息, socket.write读流,通过流的方式接收到数据
server.maxConnections = 4;
server.getConnections(function(err,count){
socket.write(`欢迎光临,当前人数为${count},总容纳数${server.maxConnections}人\r\n`);
socket.write(`请输入用户名:\r\n`);
})
socket.setEncoding('utf8')
let nickName;//存储用户名
socket.setEncoding('utf8')
socket.on('data' , function(chunk){//监听输入
chunk = chunk.replace(/\r\n/,'');//chunk自带换行回车
if(nickName){//把说的内容给别人看
Broadcast(nickName, chunk)
}else{
nickName = chunk;
client[chunk] = socket;
}
});
})
function Broadcast(nickName, chunk){
Object.keys(client).forEach(nick => {
if(nickName != nick){
client[nick].write(`${nickName}:${chunk}\r\n`)
}
});
}
//监听服务器关闭事件
server.on('close',function(){
console.log("服务器关闭")
})
下面是我们写的全部内容
//node实现tcp协议 给我们提供了一个包 net模块
//tcp 交互也要有服务端和客户端
//客户端: 可以通过任意一个端口号给服务发请求
//服务端:接受并且响应
let net = require('net');
//创建服务端
//socket套接字 会话,http有请求和响应
// let server = net.createServer(function(socket){
// //请求到来的时候执行以下
// console.log('客户端链接了服务端');
// })
let server = net.createServer();
let client = {};
//每次链接服务器 socket每次都会产生新的
server.on('connection',function(socket){
//设置最大连接数
server.maxConnections = 4;
server.getConnections(function(err,count){
socket.write(`当前人数为${count},总容纳数${server.maxConnections}人\r\n`);
socket.write(`请输入用户名:\r\n`);
})
//请求到来的时候执行以下 socket是一个Duplex 双攻流,可读可写
socket.write("欢迎光临");
//读流,通过流的方式接收到数据
socket.setEncoding('utf8');
//监听输入
let nickName;
//存储用户名
socket.setEncoding('utf8')
socket.on('data' , function(chunk){
chunk = chunk.replace(/\r\n/,'');
if(nickName){
//把说的内容给别人看
Broadcast(nickName, chunk)
}else{
//chunk自带换行回车
nickName = chunk;
client[chunk] = socket;
}
//server.close();//关闭自己 如果触发了close事件就不会在接收新的请求了,
//server.unref(); //表示关闭 没有客户端,所有人都退出,链接会自己关闭,不会触发close事件
});
//end 服务端把客户端关掉了,,,
//socket.end();
})
function Broadcast(nickName, chunk){
Object.keys(client).forEach(nick => {
if(nickName != nick){
client[nick].write(`${nickName}:${chunk}\r\n`)
}
});
}
// (端口号,服务器地址默认不写,511(可以接收多少个请求))
//监听成功会自动走回调
let port = 3000;
server.listen(port,function(){
console.log(`server start ${port}`);
})
//如果端口被占用,我们重启一个端口号
server.on('error',function(err){
if(err.code == 'EADDRINUSE'){
server.listen(++port)
}
})
server.on('close',function(){
console.log("服务器关闭")
})
多功能聊天室
-
如果说话的时候富裕一些特殊意义,可以自己增加一些标识
-
look: 看所有的在线人数
-
say:zs: 私聊
-
rename: 重命名
-
all: 广播
-
我们有个对象 clinet 当前的人{127.0.0.1}
-
当然都是本地的,所以每个人都是这个,但是不可能同一个端口发出两个socket ,假设第一个端口是{127.0.0.1:8080},另一个是8081,并且我们放歌对象,默认匿名,一级当前是哪个sokect
-
{127.0.0.1:8080:{nickname:'匿名',socket:socket}}
let net = require('net');
let client = {};
let server = net.createServer(function(socket){
server.maxConnections = 4;
server.getConnections(function(err,count){
socket.write(`当前人数为${count},总容纳数${server.maxConnections}人\r\n`);
socket.write(`请输入用户名:\r\n`);
})
let key = socket.remoteAddress + socket.remotePort; // 远程地址和远程端口号
console.log(key);
socket.setEncoding('utf8');
client[key] = {nickName:'匿名',socket:socket}
socket.on('data' , function(chunk){
chunk = chunk.replace(/\r\n/,'');
let char = chunk.split(':')[0];
let content = chunk.split(':')[1];
switch(char){
case 'look':
showList(socket);
break;
case 'say':
private(content , chunk.split(':')[2],client[key].nickName);
break;
case 'rename':
rename(key, content);
break;
case 'all':
Broadcast(key , chunk, client[key].nickName)
break;
}
// key = socket.remoteAddress + socket.remotePort
// client[key] = {nickName:'匿名',socket:socket}
function showList(socket){
let users = [];
Object.keys(client).forEach(key => {
users.push(client[key].nickName)
});
socket.write(`当前用户列表:\r\n${users.join('\r\n')}\r\n`)
}
function rename(key , chunk){
client[key].nickName = chunk;
}
function private(nickName, content , n){
let s;
Object.keys(client).forEach(key => {
if(client[key].nickName === nickName){
s = client[key].socket
}
});
s.write(`${n}: ${content}\r\n`)
}
function Broadcast(nick , chunk , nickName){
Object.keys(client).forEach(key => {
console.log(key,nick)
if(key != nick){
client[key].socket.write(`${nickName}:${chunk}\r\n`)
}
});
}
r.unref();
});
})
let port = 3000;
server.listen(port,function(){
console.log(`server start ${port}`);
})
tcp写服务端
let net = require('net');
let server = net.createServer(function(socket){
socket.write('hello');
socket.on('data',function(data){
console.log(data);
})
}).listen(3000)
//模拟客户端,并不是通过服务器
let net = require('net');
let socket = net.createConnection({port:3000},function(){
//同一次请求sockect就是同一个
socket.write('hi');
socket.on('data',function(data){
console.log(data);
})
})
