博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP与UDP
阅读量:5930 次
发布时间:2019-06-19

本文共 5983 字,大约阅读时间需要 19 分钟。

TCP

·TCP(Transmission Control Protocol传输控制协议)是一个可靠的面向连接的传输层协议

  TCP/IP分层模型分为了七层,在每一层中都包含了一些相对独立的具体的协议。从上往下分为应用层、表示层、会话层、传输层、网络层,数据链路层和物理层。

 

  tcp数据包控制位URG、ACK、PSH、PST、SYN、FIN,对tcp的连接、传输和断开进行指挥。

 

·它可以让你将数据从一台计算机完整有序的传输到另一台计算机,内置机制能够控制数据包的延迟率及丢包率不会太高

·发送方将数据转为字节流分成,将数据交给IP层。接收方接收后重新装配成原始的数据。

  应用层发出请求(数据,有含义的,http等),发出的请求在传输层添加TCP控制信息(TCP头部+数据=>数据段segment),再传递给网络层添加IP头部标识唯一地址(IP头部+数据段=>数据包Packet),然后到达数据链路层添加MAC头部及尾部让两者的网卡进行通信,之后通过物理层(网线、光纤等)以比特流的形式进行传输。到达目标主机之后,由下向上进行解析,在数据链路层去除mac头尾,再向上到达网络层去掉IP头部,再向上到达传输层去除TCP头部,最终到达应用层得到数据。

·TCP对字符和字符编码是完全无知的,不同的编码会导致传输的字节数不同

·TCP使用流控制来确保两点之间传输数据的平衡,以防止快速的发送方淹没慢速的接收方

·TCP在传输前要经过3次握手才能形成会话,只有会话形成后,服务器端和客户端才能互相发送数据。

  TCP三次握手:第一次握手是主机A向主机B请求建立连接,发送SYN;第二次握手是主机B同意主机A的连接请求,发送SYN、ACK;第三次握手是主机A向主机B发送ACK。

·在会话过程中,服务器和客户端分别提供一个套接字(socket),这两个套接字共同形成一个连接。服务器和客户端通过套接字进行通信

TCP服务器

开发过程中主要控制的是应用层和传输层。

net模块用于实现TCP服务器端和客户端之间的通信。

    ·options参数:

    -allowHalfOpen:是否允许半开连接。属性值为false时,TCP服务器收到客户端的FIN包时会回发FIN包,为true时,服务器收到客户端FIN包不回发FIN包

    ·connectionListener=function(socket){}客户端连接时的回调函数

    -socket表示服务器监听的socket端口对象

  ·返回被创建的服务器server

  ·listen(port,[host],[backlog],[callback])  

    -port监听的端口号

    -host监听的IP地址或主机名

    -backlog等待队列中的最大数量(默认511)

创建一个tcpserver.js

var net = require('net');var util = require('util');//net.Socket 双工流 Dupluxvar server = net.createServer({allowHalfOpen:true},function(socket){  console.log(util.inspect(socket.address()));  //查看当前连接数量  server.getConnections(function(err,count){      console.log(count);  });    socket.on('error',function(err){
//监听客户端的错误 console.log(err); socket.destroy(); });  socket.setEncoding('utf8');//可读流的方法   socket.on('data',function(data){    console.log(data);   })   socket.on('close',function(err){
//end事件与close事件的区别是:close一定会触发,end则不一定触发 console.log(err); socket.destroy(); })})server.on('error',function(err){
//监听服务器端的错误 console.log(err);});server.listen(8089,function(){ console.log(util.inspect(server.address())); setTimeout(function(){ server.close();//客户端全都断开后才会关闭服务端 },3000)});server.on('close',function(err){ console.log('服务器端正常关闭');});

写一个tcpSocket.js

var net = require('net');var util = require('util');var fs = require('fs');//net.Socket 双工流 Dupluxvar ws = fs.createWriteStream('./socket.txt');var server = net.createServer({allowHalfOpen:true},function(socket){  socket.setTimeout(10*1000);  socket.on('timeout',function(){    socket.resume();    socket.pipe(ws,{end:false});    ws.write(socket.remoteAddress)  });})server.on('error',function(err){  console.log(err);});server.listen(8089,function(){  console.log(util.inspect(server.address()));});

 socket

  ·net.socket代表一个socket端口对象

  ·socket端口对象可用来读取客户端发送的流数据,读到数据时触发data事件

    -socket.on('data',function(){})

  ·创建socket: var socket = new net.Socket([options])

    -options

      -fd socket文件描述符

      -type 客户端协议,tcp4或tcp6

      -allowHalfOpen是否允许半开连接

  .连接TCP服务器:socket.connect(port,[host],[connectListener])

    -port 端口

    -host主机地址

    -connectListener 连接成功后的监听

  ·向服务器发送数据:socket.write(data,[encoding],[callback])

    -data 写入的数据

    -encoding 编码

 创建一个tcpClient.js

var net = require('net');var util = require('util');var socket = new net.Socket({allowHalfOpen:true});socket.setEncoding('utf8');socket.connect(8089,'localhost',function(){  socket.write('hello');//客户端向服务端发送数据  socket.on('data',function(data){//客户端接收来自服务器的方法    console.log(data);  });});

 net类方法

  ·net.isIP 判断字符串是否是IP

  ·net.isIPv4 是否是IPv4地址

  ·net.isIPv6 是否IPv6地址

UDP

  tcp是基于连接的协议,进行通信前客户端与服务器要先建立连接。UDP是面向非连接的协议,可能直接发数据包

  UDP不要求分组顺序到达传输层中

  受网络影响可能丢失数据包

  资源消耗少,处理速度快,适合音频、视频和普通数据传输

  UDP协议中的包成为数据报datagram

  UDP协议不区分客户端和服务端的概念,都可以创建socket对象

    ·var socket = dgram.createSocket(type,[callback])

      ·type 协议类型可以是udp4或udp6

      ·callback = function(msg,rinfo)收到数据时的回调函数

        -msg收到的数据

        -rinfo

          -address 发送者的IP

          -family 地址类型

          -port发送者的socket端口号

          -size发送者发送的数据字节数

    ·绑定地址和端口  socket.bind(port,[address],[callback])

    ·发送数据 socket.send(buf,offset,length,port,address,[callback])

      -buf 要发送的数据buffer

      -offset从缓存区中第几个字节开始发送数据

      -length发送数据的字节数

      -port接收数据的端口号

      -address 接收数据的IP地址

      -callback function(err,bytes){}发送完毕时所调的回调函数

        -err 发送出错时触发的错误对象

        -bytes发送数据的字节数

创建一个udpServer.js

var dgram = require('dgram');var socket = dgram.createSocket('udp4');socket.on('message',function(msg,rinfo){  console.log(msg.toString());  console.log(rinfo);   socket.send(msg,0,msg.length,rinfo.port,rinfo.address);});socket.bind(41234,'localhost');

创建一个udpClient.js

var dgram = require('dgram');var socket = dgram.createSocket('udp4');socket.on('message',function(msg,rinfo){    console.log(msg.toString());    console.log(rinfo);});socket.send(new Buffer('珠峰培训'),0,6,41234,'localhost',function(err,bytes){    console.log('发送了个%d字节',bytes);});socket.on('error',function(err){    console.error(err);});

 创建一个即时通讯的tcp聊天chatServer.js

/** * 1.创建一个服务器 * 2. 客户端可以连接服务器 * 3.客户端可以发言,然后广播给大家 * 4.客户端连接和退出后都要通知大家。 * 5.显示当前的在线人数 */var net = require('net');var util = require('util');var clients = {};var server = net.createServer(function(socket){ var nickname; socket.setEncoding('utf8');    server.getConnections(function(err,count){        socket.write('欢迎光临,当前在线'+count+'人,请输入用户名\r\n>');    }); socket.on('data',function(data){   //console.log(new Buffer(data));   data = data.replace(/\r\n/,'');   if(nickname){       broadcast(nickname,nickname+":"+data+'\r\n');   }else{       nickname = data;       clients[nickname] = socket;       broadcast(nickname,nickname+'加入了聊天室\r\n');   } }); socket.on('end',function(){     broadcast(nickname,nickname+'离开了聊天室\r\n');     clients[nickname].destroy();     delete clients[nickname]; });    socket.on('error',function(){    });    socket.on('close',function(){    });})function broadcast(nickname,msg){    for(var name in clients){        if(nickname != name)            clients[name].write(msg);    }}server.listen(8088);

 

转载于:https://www.cnblogs.com/web-fengmin/p/6396766.html

你可能感兴趣的文章
reactnative(2) - Navigator 使用案例
查看>>
《3+1团队》【Beta】Scrum meeting 1
查看>>
nyoj 740 “炫舞家“ST
查看>>
Generating WCF Proxy using SvcUtil.exe
查看>>
[转] HTML5中meta属性的使用详解
查看>>
sicily 1828 Minimal(dp)
查看>>
KMP算法
查看>>
CS100 Homework
查看>>
CPU选择intel还是amd
查看>>
【嵌入式开发】嵌入式 开发环境 (远程登录 | 文件共享 | NFS TFTP 服务器 | 串口连接 | Win8.1 + RedHat Enterprise 6.3 + Vmware11)...
查看>>
C++读取配置文件
查看>>
Oracle sql中start with,connect by伪语句用法
查看>>
493. Reverse Pairs
查看>>
Deep learning:四十(龙星计划2013深度学习课程小总结)
查看>>
无符号整型指定比特位置1
查看>>
枚举\位域\结构综合实验
查看>>
MySQL出错:ERROR 1045 (28000)的解决方法
查看>>
win下 git gui 使用教程
查看>>
POJ - 2253 Frogger(Dijkstra)
查看>>
Python之常用模块(re,时间,random,os,sys,序列化模块)(Day20)
查看>>