当前位置:网站首页 / Node.js / 正文

[AY-Node.js]写给自己的NodeJs-通讯系统-tcp客户端【三】[16]

时间:2015年10月26日 | 作者 : aaronyang | 分类 : Node.js | 浏览: 2925次 | 评论 0

var net=new net.Socket([options])

options 如下:

  fd,一个现存的socket的文件描述符

  type,用于指定客户端所使用的协议,可以指定:tcp4,tcp6,unix

  allowHalfOpen,默认false,为false时候,当TCp服务器接受客户端发送的一个FIN包会回发一个FIN包,当属性为true的时候,当TCP服务器端接受到客户端发送的一个FIN包,不会发FIN包,这使得TCP服务器可以继续向客户端发送数据,但是不会继续接受客户端发送的数据,开发者必须调用end方法来关闭socket连接。


demo:客户端与服务器端建立连接,互相发送数据

新建tcpserver.js,通过socket.write方法,像客户端发送数据

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var server=net.createServer();
server.on('connection', function (socket) {
    console.log('连接建立');
    socket.setEncoding('utf-8');
    socket.on('data', function (data) {
        console.log('接受到数据:' + data);
        socket.write('服务器已经接收到你发送的数据:'+data);//发送给客户端
    })
}).listen(8888,'localhost');


新建tcpclient.js,通过socket.write方法,像服务端发送数据

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var client=new net.Socket();
client.setEncoding('utf-8');
client.connect(8888,'localhost',function(){
    console.log('连接到服务器8888');
    client.write('你好!ay');
})

//接受服务端数据
client.on('data', function (data) {
    console.log('服务端发送的数据:' + data);
})

s1.gif

socket有error事件,发生错误时候触发,我们可以使用destroy()方法销毁该socket端口对象

修改tcpclient.js代码,增加error处理,先运行tcpserver.js,然后运行tcpclient.js然后关掉tcpserver.js看发生什么错误

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var client=new net.Socket();
client.setEncoding('utf-8');
client.connect(8888,'localhost',function(){
    console.log('连接到服务器8888');
    client.write('你好!ay');
})

//接受服务端数据
client.on('data', function (data) {
    console.log('服务端发送的数据:' + data);
})
client.on('error', function (err) {
    console.log('发生错误%s', err.code);
    client.destroy();
})

blob.png

在服务端增加error处理,用来当客户端发生错误的时候的处理。  运行两个js,然后关闭tcpclient.js的运行

blob.png

双方都可以调用socket.end方法关闭客户端或服务端连接

正常情况下,客户端断开连接,服务端是不会关闭的,好比玩LOL,你退出游戏,不代表服务器关掉。服务端可以在客户端end方法


tcpclient.js   连接后end,结束连接

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var client=new net.Socket();
client.setEncoding('utf-8');
client.connect(8888,'localhost',function(){
    console.log('连接到服务器8888');
    client.write('你好!ay');
    client.end('再见!ay');
})

//接受服务端数据
client.on('data', function (data) {
    console.log('服务端发送的数据:' + data);
})
client.on('error', function (err) {
    console.log('发生错误%s', err.code);
    client.destroy();
})

tcpserver.js接受他的end

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var server=net.createServer();
server.on('connection', function (socket) {
    address=socket.address();
    console.log('连接建立');
    socket.setEncoding('utf-8');
    socket.on('data', function (data) {
        console.log('接受到数据:' + data);
        socket.write('服务器已经接收到你发送的数据:'+data);//发送给客户端
    });
    socket.on('error', function (err) {
        console.log('与客户端通讯发生错误%s', err.code);
        socket.destroy();
    })
    socket.on('end', function () {
        console.log('%j客户端断开连接',address);
    })

}).listen(8888,'localhost');

blob.png

从上图的红色的正方形,说明,客户端断开了,但是服务端没有,我们使用unref结束

blob.png

socket.on('close',function(error){

    if(error){


    }else{

    

  }

})

我们可以在使用了unref后使用server.ref()阻止程序退出

2015-10-26 ======== AYUI www.ayjs.net AY 杨洋原创编写,请不要转载谢谢===============

限制连接数量,超过2个,服务拒绝,服务器关闭

server.getConnections(function (err, count) {
    if(count==2){
        server.close();
    }
})

代码设置

var server=net.createServer();
server.maxConnections=2;

修改var server=net.createServer({allowHalfOpen:true});

先运行tcpserver.js然后tcpclient.js,然后client端会报错误

blob.png

错误原因: 客户端关闭连接,向服务器发送一个通知关闭的FIN包,默认allowHalfOpen为false时候,TCP服务器会回发一个ACK包,表示确认客户端关闭了连接,服务器端也会关闭,客户端接收服务器端发送的ACK包,知道服务器也关闭了自己。如果allowHalfOpen为true,那么服务器就不发ACK包了,所以客户端不知道,但是服务器端知道客户端把它关了(但是服务器仍然可以向客户端发数据,但是不再接收该客户端发送的数据了)。

在上面的例子中,我们用了tcp的unref方法,当最后一个客户端关闭连接后就会退出程序,这时候客户端没有没有收到关闭连接的消息,却收到了服务端退出的消息,所以报错了。


如果为true,我们在服务端的end方法,要去通知客户端断开了连接才行

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var server=net.createServer({allowHalfOpen:true});
server.maxConnections=2;
server.on('connection', function (socket) {
    address=socket.address();
    console.log('连接建立');
    socket.setEncoding('utf-8');
    socket.on('data', function (data) {
        console.log('接受到数据:' + data);
        socket.write('服务器已经接收到你发送的数据:'+data);//发送给客户端
    });
    socket.on('error', function (err) {
        console.log('与客户端通讯发生错误%s', err.code);
        socket.destroy();
    })
    socket.on('end', function () {
        console.log('%j客户端断开连接',address);
        socket.end();
        server.unref();
    })
    //server.getConnections(function (err, count) {
    //    if(count==2){
    //        server.close();
    //    }
    //})

}).listen(8888,'localhost');
server.on('close', function (err) {
    console.log('tcp服务器被关闭');
})

发送文件

新建tcpSend.js文件,通过fs读写文件,在data的时候socket.write这个data

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var server=net.createServer();
var fs=require('fs');
server.on('connection', function (socket) {
    console.log('连接建立');
    //socket.setEncoding('utf-8');
    var readStream=fs.createReadStream('d://MyWifi.rar');
    readStream.on('data', function (data) {
        var flag=socket.write(data);
        console.log('write返回值:'+flag);
        console.log('缓存队列中当前缓存了%d字符',socket.bufferSize);
    })
    socket.on('data', function (data) {
        console.log('客户数据:' + data);
    })
    socket.on('drain', function () {
        console.log('缓存区数据已全部发送');
    })
}).listen(8888,'localhost')

新建tcpReceiver.js

/**
 * Created by aaronyang on 2015/10/26.
 */
var net=require('net');
var client=new net.Socket();
var fs=require('fs');
var file=fs.createWriteStream('./mywifi.rar');
//client.setEncoding('utf-8');
client.connect(8888,'localhost', function () {
    console.log('与服务器连接成功');
    client.write('你好,ay');
    console.log('发送%d字节数据', client.bytesWritten);
});

file.on('end',function(){
    console.log('文件接收完成,共接收%d字节数据',file.bytesWritten);
});
client.on('data', function (data) {
    file.write(data);
})

先运行server,再运行client

简单的聊天室demo

 var net = require('net');
 var server = net.createServer();
 var sockets = [];
 server.on('connection', function(socket) {
     console.log('got a new connection');
     sockets.push(socket);
     console.log('sockets length:', sockets.length);
     socket.on('data', function(data) {
         console.log('got data:', data.toString());
         sockets.forEach(function(otherSocket) {
             if (otherSocket !== socket) {
                 otherSocket.write(data);
             }
         });
     });
     socket.on('close', function() {
         console.log('connection closed');
         var index = sockets.indexOf(socket);
         sockets.splice(index, 1);
         console.log('sockets length:', sockets.length);
     });
 });
 server.on('error', function(err) {
     console.log('Server error:', err.message);
 });
 server.on('close', function() {
     console.log('Server closed');
 });
 server.listen(4001);

其他属性判断

net.isIP('aaa')判断是不是ip地址

net.isIPv4

net.isIPv6


2015-10-26 ======== AYUI       www.ayjs.net      AY         杨洋原创编写,请不要转载谢谢===============

推荐您阅读更多有关于“nodejs,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

抖音号:wpfui,可以看到我的很多作品效果

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF,目前工作繁忙,不接任何活

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

兼容XP到win10,vs2015/2017/2019,最新AYUI:7.6.5.5

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表