TCP与UDP,TCP服务器与客户端,UDP服务器与客户端

Posted 别Null.了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP与UDP,TCP服务器与客户端,UDP服务器与客户端相关的知识,希望对你有一定的参考价值。

目录

TCP

主要特点

TCP的三次握手与四次挥手

net模块 

UDP

主要特点

UDP与TCP的区别

dgram模块

TCP的服务器与客户端

创建TCP服务器

创建TCP客户端 

UDP的服务器与客户端

创建UDP服务器

创建UDP客户端


TCP

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。TCP旨在适应支持多网络应用的分层协议层次结构。 

主要特点

TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式:

  • 可靠通信方式;
  • 基于流的方式;
  • 面向连接;
  • 在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
  • 通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。

TCP的三次握手与四次挥手

TCP是因特网中的传输层协议,使用三次握手协议建立连接。建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。

                    

三次握手

  1. 客户端A发送连接请求到服务器B;
  2. 服务器B接收到客户端A发送的信息后必须确认信息,于是给服务器B发送状态码,并进入SYN_RECV状态;
  3. 客户端A接收到服务器B的状态后回应服务器端B,并进入Established状态 。

三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。

四次挥手

  1. 若客户端A认为数据发送完成,则它需要向服务端 B 发送连接释放请求。
  2. B收到连接释放请求后,告诉应用层要释放TCP连接,然后会发送ACK包,并进入CLOSE_WAIT状态,此时表明A到B的连接已经释放,不再接收A发的数据了。但是因为TCP连接是双向的,所以B仍旧可以发送数据给A。
  3. B如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态。
  4. A 收到释放请求后,向 B 发送确认应答,此时A进入TIME-WAIT状态。当B收到确认应答后,也便进入CLOSED状态。

为什么连接时候是三次握手,关闭连接时候需要四次挥手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。

net模块 

net核心模块用于创建TCP连接和服务,封装了大部分底层的类和方法。

使用时,需导入该模块: const net = require('net') 

net方法

net.createServer([options][, connectionListener])
创建一个 TCP 服务器。参数 connectionListener 自动给 'connection' 事件创建监听器。

net.connect(path[, connectListener])
创建连接到 path 的 unix socket 。参数 connectListener 将会作为监听器添加到 'connect' 事件上。返回 'net.Socket'。

net.Socket 对象是 TCP的抽象。net.Socket 实例实现了一个双工流接口。 他们可以在用户创建客户端(使用 connect())时使用, 或者由 Node 创建它们,并通过 connection 服务器事件传递给用户。

UDP

Internet协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。

主要特点

  • 面向无连接。无连接协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。
  • 支持一对多,多对多,多对一的传输方式。
  • UDP信息包的标题很短,只有8个字节。
  • UDP是面向报文的。
  • 虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。

UDP与TCP的区别

UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。

TCPUDP
是否连接面向连接无连接
是否可靠可靠传输,使用流量控制不可靠传输,不使用流量控制
连接对象个数只能是一对一通信支持一对一,一对多,多对一和多对多
传输方式面向字节流面向报文
首部开销首部字节最小20最大60首部开销小,仅8字节
适用场景要求可靠传输的应用(文件传输)实时应用(IP电话,视频会议等)

TCP向上层提供面向连接的可靠服务,UDP向上层提供无连接不可靠服务。

虽然UDP并没有TCP传输准确,但适用于实时性较高的地方。

对数据准确性要求高,速度可以相对较慢的可选择TCP。 

dgram模块

在Node.js中,提供了dgram模块,用于创建UPD服务器与客户端,以及实现UDP服务器与客户端之间的通信。

使用时,需导入该模块: const dgram = require('dgram') 

TCP的服务器与客户端

注意:在启动时,我们应该先启动服务器端再启动客户端。(就相当于用户给客服打电话,只有当客服存在时,用户的电话才可以拨通,客服就相当于服务器端,用户就相当于客户端)

创建TCP服务器

//导入net模块
const net = require('net')
//创建TCP服务器
const server = net.createServer((client)=>{   //'client'表示的是客户端
    var clientNo = 0   //为每个连接到服务器的客户端编号
    console.log(clientNo+'号客户端已经连接');
    //绑定“end”事件,客户端断开连接时触发
    client.on('end',function(){
        console.log(clientNo+'号客户端已经断开');
    })
    client.write(clientNo+'号客户端,你好!');
    client.pipe(client);
    //绑定‘data’事件,接收数据时触发
    client.on('data',(data=>{
        console.log(clientNo+'号客户端发送的数据是:'+data.toString());
    }))
})
//绑定‘error’事件,当连接发生错误时打印错误信息
server.on('errot',(err=>{
    throw err;
}))
//启动监听,指定监听的接口
server.listen(8234,()=>{
    console.log('TCP服务器端已经启动')
})

创建TCP客户端 

const net = require('net')
//创建TCP客户端
var client = net.Socket();
//连接服务器:调用connect方法
client.connect(8234,'127.0.0.1',()=>{
    console.log('已经连接到服务器');
    client.write('我是TCP服务器');  //向服务器发送数据
})

//接收服务器端数据:绑定‘data’事件
client.on('data',(data)=>{
    console.log('接收的服务器端数据:'+data.toString());
})
//监听‘end’事件
client.on('end',()=>{
    console.log('结束数据!');
})

 示例结果:

UDP的服务器与客户端

创建UDP服务器

//导入dgram模块
const dgram = require('dgram');
//创建dgram.Socket对象(服务器端---数据的接收端)
const server = dgram.createSocket('udp4');
//绑定“error”事件
server.on('error',(err=>{
    console.log(`服务器异常:${err.stack}`);
}))
//绑定‘message’事件,参数msg客户端发送的数据,参数rinfo封装了客户端的信息(包括地址、端口号等)
server.on('message',((msg,rinfo)=>{
    var str_msg = msg.toString();
    console.log(`服务器接收来自:${rinfo.address}:${rinfo.port}的${str_msg}`);
    console.log(rinfo);
    server.send('西安邮电大学',rinfo.port,rinfo.address);  //向客户端发送数据
}))
//注册监听
server.on('listening',()=>{
    var server_address = server.address();  //获取服务器端的地址
    console.log(`服务器监听:${server_address.address}:${server_address.port}`);
})
//绑定端口:对来自于该端口的信息进行监听
server.bind(41234);

创建UDP客户端

const dgram = require('dgram');
const client_msg = Buffer.from('你好,我是UDP的客户端');
//创建客户端的Socket
const client = dgram.createSocket('udp4');
//绑定事件
client.on('close',()=>{
    console.log('Scoket已关闭')
})
client.on('error',(err=>{
    console.log(err);
}))
client.on('message',((msg,rinfo)=>{
    if(msg == 'exit'){
        client.close();
    }
    console.log(`接收到来自服务器${rinfo.address}:${rinfo.port}的信息:${msg.toString()}`);
}))
//向服务器端发送数据    41234是服务器端口,回调函数
client.send(client_msg,41234,'localhost',(error=>{
    if(error){
        client.close();
    }
}))

示例结果:

以上是关于TCP与UDP,TCP服务器与客户端,UDP服务器与客户端的主要内容,如果未能解决你的问题,请参考以下文章

网络套接字(Udp与Tcp应用)

TCP与UDP的区别

UDP与TCP

Python 绝技 —— UDP 服务器与客户端

TCP与UDP的区别

当UDP协议客户端给TCP协议服务器发数据会发生什么