7 网络通信(上)
文章目录
- 网络通信概述
- ip地址
- ip的作用
- ip地址的分类
- 私有ip
- 掩码和广播地址
- linux 命令(ping ifconfig)
- 查看或配置网卡信息:ifconfig(widows 用ipconfig)
- 测试远程主机连通性:ping
- 路由查看
- 端口
- 端口是怎样分配的
- 知名端口
- 动态端口
- 查看端口及谁使用了端口
- 查询端口状态netstat / 一般搭配grep一起使用
- 查看具体的端口由什么进程在使用lsof
- 路由追踪(traceroute)
- 总结
- socket简介
- TCP和UDP的使用场景
- 不同电脑上的进程之间如何通信
- 什么是 socket
- 创建 socket
- python3编码转换
- udp
- udp基本网络框架
- udp服务端代码
- udp客户端代码
- 小tips
- 阿里云服务器udp演示
- 补充(kill)
- tcp
- tcp的特点
- 面向连接
- 可靠传输
- TCP 与 UDP 的不同点
- TCP的基本网络框架
- TCP服务端代码
- 关于listen
- TCP用户端代码
- tcp示例样例--文件下载器雏形
- 补充--高级传参
- 代码
- tcp的三次握手
- tcp的四次挥手
- tcp的长连接和短连接
- 通信的全程图
- 短连接和长连接的区别
- 短链接的操作步骤:
- 长连接的操作步骤:
- TCP 长/短连接的优点和缺点
- TCP 长/短连接的应用场景
网络通信概述
WAN:
一种跨越大的、地域性的计算机网络的集合。通常跨越省、市,甚至一个国家。广域网包括大大小小不同的子网,子网可以是局域网,也可以是小型的广域网
LAN:
顾名思义,LAN是指在某一区域内由多台计算机互联成的计算机组。一般是方圆几千米以内。局域网可以实现文件管理、应用软件共享、打印机共享、工作组内的日程安排、电子邮件和传真通信服务等功能。局域网是封闭型的,可以由办公室内的两台计算机组成,也可以由一个公司内的上千台计算机组成。
ip地址
ip的作用
IP地址的作用是唯一标识网络中的设备,使得设备能够在网络中进行通信。它类似于门牌号码,用于确定设备的位置和身份。IP地址可以用于寻找和连接其他设备,发送和接收数据包,并在Internet上进行通信。IP地址的作用还包括路由选择、网络管理和安全控制等方面。
一句话的话ip 地址就是用来在网络中标记一台电脑,比如 192.168.1.1在本地局域网上是唯一的。
ip地址的分类
每一个 IP 地址包括两部分:网络地址和主机地址
私有ip
在这么多网络 IP 中,国际规定有一部分 IP 地址是用于我们的局域网使用,也就是属于私网 IP,不在公网中使用的,它们的范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
值得关注的是:
IP 地址 127.0.0.1~127.255.255.255 用于回路测试,
如:127.0.0.1 可以代表本机 IP 地址,用 http://127.0.0.1 就可以测试本机中配
置的 Web 服务器
掩码和广播地址
子网掩码:互联网是由许多小型网络构成的,每个网络上都有许多主机,这样便构成了一个有层次的结构。IP地址在设计时就考虑到地址分配的层次特点,将每个IP地址都分割成网络号和主机号两部分,以便于IP地址的寻址操作。
子网掩码有两个功能:
- 将一个IP地址划分为网络位和主机位
- 判断两个设备是否在同一个子网
广播地址是专门用于同时向网络中所有工作站进行发送的一个地址。
在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址,广播的分组传送给host ID段所涉及的所有计算机。例如,对于10.1.1.0 (255.255.255.0 )网段,其广播地址为10.1.1.255 (255 即为2 进制的11111111 ),当发出一个目的地址为10.1.1.255 的分组(封包)时,它将被分发给该网段上的所有计算机。
linux 命令(ping ifconfig)
查看或配置网卡信息:ifconfig(widows 用ipconfig)
测试远程主机连通性:ping
通常用 ping 来检测网络是否正常,直接ping (网址/ip)即可
路由查看
route -n
内核 IP 路由表
目标 | 网关 | 子网掩码 |
---|---|---|
0.0.0.0 | 192.168.19.2 | 0.0.0.0 |
169.254.0.0 | 0.0.0.0 | 255.255.0.0 |
192.168.19.0 | 0.0.0.0 | 255.255.255.0 |
0.0.0.0 代表任意目的地
网关就是转发数据的设备
路由表是从上往下匹配的
端口
在unix/linux的使用中,实际上网络沟通是进程与进程之间进行的沟通,举个例子就是,我电脑上的QQ进行和别人电脑上的QQ进程进行沟通,而端口负责的就是在同一ip下的,关于具体到进程这一方面的交互。
端口是通过端口号来标记的,端口号只有整数,范围是从 0 到 65535
注意:端口数不一样的 unix/linix 系统不一样,还可以手动修改
端口是怎样分配的
端口号不是随意使用的,而是按照一定的规定进行分配。端口的分类标准有好几种,我们这里不做详细讲解,只介绍一下知名端口和动态端口
知名端口
知名端口是众所周知的端口号,范围从 0 到 1023
端口号 | 说明 |
---|---|
80 | 端口分配给 HTTP 服务 |
21 | 端口分配给 FTP 服务 |
22 | 端口分配给 ssh |
443 | 端口分配给https |
一般情况下,如果一个程序需要使用知名端口的需要有 root 权限
动态端口
动态端口的范围是从 1024 到 65535。之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。
动态分配是指当一个系统程序或应用程序程序需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配一个供它使用。当这个程序关闭时,同时也就释放了所占用的端口号。
查看端口及谁使用了端口
查询端口状态netstat / 一般搭配grep一起使用
netstat [-an]
查看端口状态
例子:
此时就可以简单看出在我们本地的widows是59173端口和服务器的22号端口进行相连。
查看具体的端口由什么进程在使用lsof
sudo lsof -i [tcp/udp]:2425 必须是 root 才能查看
sudo lsof -i tcp:22 查看哪一个进程用了这个端口
ps -elf |grep udp_server 查看某个进程是否还在
参考链接:
lsof
ps
路由追踪(traceroute)
使用方式:
# window下
tracert ip地址
# linux下
traceroute ip地址
总结
端口有什么用呢 ? 我们知道,一台拥有 IP 地址的主机可以提供许多服务,比如HTTP(万维网服务)、FTP(文件传输)、SMTP(电子邮件)等,这些服务完全可以通过 1 个 IP 地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠 IP 地址,因为 IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP 地址+端口号”来区分不同的服务的。 需要注意的是,端口并不是一一对应的。比如你的电脑作为客户机访问一台 WWW 服务器时,WWW 服务器使用“80”端口与你的电脑通信,但你的电脑则可能使用“3457”这样的端口。
socket简介
先简单介绍一下tcp和udp,后面部分会再进行详细的介绍:
TCP是面向连接的协议,在收发数据前必须和对方建立可靠的连接,建立连接的3次握手、断开连接的4次挥手,为数据传输打下可靠基础;UDP是一个面向无连接的协议,数据传输前,源端和终端不建立连接,发送端尽可能快的将数据扔到网络上,接收端从消息队列中读取消息段。
由此可以看出:UDP 服务器端不需要调用监听(listen)和接收(accept)客户端连接,而客户端也不需要连接服务器端(connect)。UDP协议中,任何一方建立socket后,都可以用sendto发送数据、用recvfrom接收数据,不必关心对方是否存在,是否发送了数据。
TCP和UDP的使用场景
为了实现TCP网络通信的可靠性,增加校验和、序号标识、滑动窗口、确认应答、拥塞控制等复杂的机制,建立了繁琐的握手过程,增加了TCP对系统资源的消耗;TCP的重传机制、顺序控制机制等对数据传输有一定延时影响,降低了传输效率。TCP适合对传输效率要求低,但准确率要求高的应用场景,比如万维网(HTTP)、文件传输(FTP)、电子邮件(SMTP)等。
UDP是无连接的,不可靠传输,尽最大努力交付数据,协议简单、资源要求少、传输速度快、实时性高的特点,适用于对传输效率要求高,但准确率要求低的应用场景,比如域名转换(DNS)、远程文件服务器(NFS)等。
不同电脑上的进程之间如何通信
首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在 1 台电脑上可以通过进程号(PID)来唯一标识一个进程,但是在网络中这是行不通的。其实 TCP/IP 协议族已经帮我们解决了这个问题,网络层的“ip 地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用进程(进程)。这样利用协议,ip 地址,端口就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。
什么是 socket
socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于Socket 来完成通信的:
例如我们每天浏览网页、QQ 聊天、收发 email 等等
创建 socket
在 Python 中 使用 socket 模块的函数 socket 就可以完成:
import socket
socket.socket(AddressFamily, Type)
说明:
函数 socket.socket 创建一个 socket,该函数带有两个参数:
- Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者AF_UNIX(用于同一台机器进程间通信),实际工作中常用 AF_INET
- Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
创建一个 tcp socket(tcp 套接字)
import socket
# 创建 tcp 的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# ...这里是使用套接字的功能(省略)...
# 不用的时候,关闭套接字
s.close()
创建一个 udp socket(udp 套接字)
import socket
# 创建 udp 的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ...这里是使用套接字的功能(省略)...
# 不用的时候,关闭套接字
s.close()
由此可以看出一个比较不一样的地方就是使用的常数是很不一样的。socket.SOCK_STREAM和socket.SOCK_DGRAM
python3编码转换
str->bytes:encode 编码
bytes->str:decode 解码
udp
udp基本网络框架
udp服务端代码
根据上文的流程图可以写出下文的代码
import socket# 1.创建一个udp的服务器名为server
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 2.服务器绑定ip地址与端口
addr=('本地的地址',2000) #写1024以上端口
server.bind(addr) #失败直接抛异常# 3.阻塞接受客户端的消息
# recvfrom函数返回的list中 list[0]返回的是客户端传回的数据,list[1]传回的是客户端的ip地址端口的消息
data,client_addr=s.recvfrom(5) # 5代表接的字节大小
print(data.decode('utf8'))
print(client_addr)# 4.根据返回的消息处理请求。略# 5.返回消息给客户端
server.sendto('很牛'.encode('utf8'),client_addr)# 6.关闭服务器
server.close()
小补充:
实际上当你运行服务端的时候,你去自己电脑命令窗口下netstat -an实际上就会发现你的对应的端口就会打开:
udp客户端代码
根据上文的流程图可以写出下文的代码
import socket
# 1.创建一个udp客户端命名为client
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 2.发送消息给服务端
dest_addr=('192.168.0.100',2000)
# client.sendto(b'hello',dest_addr)
client.sendto('howare'.encode('utf8'),dest_addr) #放汉字还是不放都行# 3.阻塞等待服务端发消息给客户端
data,_=client.recvfrom(100)
print(data.decode('utf8'))# 4.后续处理,略# 5.关闭客户端
client.close() #关闭时端口会释放
小tips
- 值得关注的是服务器端的端口需要写死端口号,这样子才可以让客户端有一个固定的访问地址。而客户端的端口号是随机生成的,所以一般来说,客户端都需要通过recvfrom中的list[1]中的元素进行知道是哪个客户端发送的消息,然后对应相对应的处理。
- 当 UDP recvfrom 内部要接的大小,少于发送的字节数,windows 报错,Linux 是不会报错,没有拿的数据直接丢弃。
- 如果采用阿里云或者腾讯云的,我们需要将服务器的那个文件放到服务器上运行,然后==服务器的bind绑定的是ifconfig中内网的值,而我们客户端发送数据sendto的时候的地址是服务器的公网的值。==下面是简单的步骤演示:
阿里云服务器udp演示
首先先配置安全组:
然后将服务器文件拖动到服务器上,并修改服务器的那个地方对应的内网ip:
先输入ifconfig:
然后修改ip:
运行服务端:
修改客户端ip:
不暴露信息,自己取修改吧,从阿里云服务器上了解其公网ip,然后在客户端上进行修改即可
运行客户端:
补充(kill)
端口占用怎么办?
ps -elf 查看进程
kill -9 进程 i
给个样例:
ps -elf|grep 2000 #查看2000号端口的使用者是谁
kill -9 对应的PID
tcp
TCP 协议,传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议
TCP 通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,“打电话”“,而udp 通信模型中,在通信开始之前,不需要建立相关的链接,只需要发送数据即可,类似于生活中,“写信””
tcp的特点
面向连接
通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。双方间的数据传输都可以通过这一个连接进行。完成数据交换后,双方必须断开此连接,以释放系统资源。
这种连接是一对一的,因此 TCP 不适用于广播的应用程序,基于广播的应用程序请使用 UDP 协议。
可靠传输
- TCP 采用发送应答机制
TCP 发送的每个报文段都必须得到接收方的应答才认为这个 TCP 报文段传输成功,每一个报文都有一个序列号。 - 超时重传
发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。TCP 为了保证不发生丢包,就给每个包一个序列号,同时序列号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。 - 错误校验
TCP 用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。 - 流量控制和阻塞管理
滑动窗口:控制双方的发送接收速度
流量控制用来避免主机发送得过快而使接收方来不及完全收下。
TCP 与 UDP 的不同点
• 面向连接(确认有创建三方交握,连接已创建才作传输。)
• 有序数据传输
• 重发丢失的数据包
• 舍弃重复的数据包
• 无差错的数据传输
• 阻塞/流量控
TCP的基本网络框架
TCP服务端代码
根据上文的流程图可得下面的代码:
import socketdef tcp_server():# 1.创建tcp的socket服务端# SOCK_STREAM代表tcp的socketserver=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2.绑定地址,注意和udp不同的是,此时我们去查看端口,此端口是没有激活的addr=('192.168.5.7',2000)server.bind(addr) #绑定,端口并没有激活# 3.监听端口server.listen(128) #listen时,端口才激活# 4.接受沟通,创建与相对应客户端相连接的套接字new_client,client_addr=server.accept()print(client_addr)# 5.截下来就是相对应的别的操作了可以send也可以recv,不过需要和客户端相对应。# 接下来就可以进行send,recv操作new_client.send('helloworld'.encode('utf8'))data=new_client.recv(100)print(data.decode('utf8'))# 6.关闭服务器,注意要先关闭client再关闭servernew_client.close()server.close()if __name__ == '__main__':tcp_server()
关于listen
在socket中,listen函数的参数数字表示等待连接队列的最大长度。具体来说,它指定了服务器端能够同时处理的最大连接数。
当一个服务器端的socket调用listen函数时,它会开始监听指定的端口号,并等待客户端的连接请求。listen函数的参数指定了服务器端能够接受的最大连接数。如果连接请求的数量超过了这个限制,那些超出的连接请求将被服务器端忽略或拒绝。
例如,如果listen函数的参数设置为5,那么服务器端最多能够同时处理5个连接请求。如果有第6个连接请求到达,它将被服务器端忽略或拒绝。
需要注意的是,listen函数的参数值并不代表服务器端能够处理的并发连接数。实际上,服务器端能够处理的并发连接数取决于多个因素,如服务器的硬件性能、操作系统的限制等。listen函数的参数值只是指定了服务器端能够接受的最大连接数,而并不代表服务器端能够同时处理这么多连接。
TCP用户端代码
根据上文的流程图可得下面的代码:
import socketdef tcp_client():# 1.创建socket对象--客户端client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2.将客户端和服务端连接,与udp不同的是,udp不需要连接,udp使用sendto加上地址进行传送数据dest_addr = ('192.168.5.7', 2000)client.connect(dest_addr)# 3.后续的recv和send操作,与服务器对应data=client.recv(5)print(data.decode('utf8'))client.send('我是男生abc123'.encode('utf8'))# 4.关闭客户端client.close()if __name__ == '__main__':tcp_client()
tcp示例样例–文件下载器雏形
补充–高级传参
补充知识:
import sysfor i in sys.argv:print(i)
此时转到终端输入:
python 这个文件
得到的输出是:
这个文件
也就是说,我们可以通过后续多加几个str类型数据,从而得到相对应的配置属性输入:
python 这个文件 ip port
输出:
这个文件 ip port
代码
服务端:
from socket import *
import sysdef get_file_content(file_name):"""获取文件的内容"""try:with open(file_name, "rb") as f:content = f.read()return contentexcept:print("没有下载的文件:%s" % file_name)def main():if len(sys.argv) != 2:print("请按照如下方式运行:python3 xxx.py 7890")returnelse:# 运行方式为python3 xxx.py 2000port = int(sys.argv[1])# 创建sockettcp_server_socket = socket(AF_INET, SOCK_STREAM)# 本地信息address = ('', port)# 绑定本地信息tcp_server_socket.bind(address)# 将主动套接字变为被动套接字tcp_server_socket.listen(128)# 值得关注的是1->多体现在这里while True:# 等待客户端的链接,即为这个客户端发送文件client_socket, clientAddr = tcp_server_socket.accept()# 接收对方发送过来的数据recv_data = client_socket.recv(1024) # 接收1024个字节file_name = recv_data.decode("utf-8")print("对方请求下载的文件名为:%s" % file_name)file_content = get_file_content(file_name)# 发送文件的数据给客户端# 因为获取打开文件时是以rb方式打开,所以file_content中的数据已经是二进制的格式,因此不需要encode编码if file_content:client_socket.send(file_content)# 关闭这个套接字client_socket.close()# 关闭监听套接字tcp_server_socket.close()if __name__ == "__main__":main()
客户端:
from socket import *def main():# 创建sockettcp_client_socket = socket(AF_INET, SOCK_STREAM)# 目的信息server_ip = '192.168.5.7'server_port = 2000# 链接服务器tcp_client_socket.connect((server_ip, server_port))# 输入需要下载的文件名file_name = input("请输入要下载的文件名:")# 发送文件下载请求tcp_client_socket.send(file_name.encode("utf-8"))# 接收对方发送过来的数据,最大接收1024个字节(1K)recv_data = tcp_client_socket.recv(1024)# print('接收到的数据为:', recv_data.decode('utf-8'))# 如果接收到数据再创建文件,否则不创建if recv_data:with open("[接收]"+file_name, "wb") as f:f.write(recv_data)# 关闭套接字tcp_client_socket.close()if __name__ == "__main__":main()
tcp的三次握手
三次握手是TCP协议中建立可靠连接的过程。在客户端和服务器之间建立连接之前,必须进行三次握手来确保双方都能够正常通信。下面是三次握手的详细步骤:
第一次握手(SYN):客户端发送一个SYN(同步)包给服务器端,请求建立连接。这个包包含一个随机生成的初始序列号(ISN)用于标识数据流的起始位置。
第二次握手(SYN-ACK):服务器接收到客户端的SYN包后,会发送一个SYN-ACK(同步-确认)包给客户端。这个包中会确认客户端的SYN,并且也会包含一个随机生成的ISN作为回应。
第三次握手(ACK):客户端接收到服务器的SYN-ACK包后,会发送一个ACK(确认)包给服务器。这个包会确认服务器的SYN,并且也会包含服务器发送的ISN加1作为回应。
完成了这三次握手之后,双方就建立了可靠的连接,可以开始进行数据传输。此时,双方都可以相互发送数据包,并且可以保证数据的可靠传输。
三次握手的目的是确保双方都能够正常收发数据,并且能够彼此接收到对方发送的数据。通过三次握手,双方可以建立起一个可靠的连接,以便进行可靠的数据传输。同时,三次握手也可以防止已失效的连接请求被服务器端误认为是新的连接请求,从而提高了连接的可靠性和安全性。
如果只存在两次握手,会出现两种可能导致死锁的情况:
死锁情况一(客户端发起连接失败):客户端发送SYN包给服务器端,但由于网络延迟或其他原因,服务器端没有收到该包。此时,客户端认为连接已经建立,进入等待状态,而服务器端并不知道客户端的存在。由于缺乏第三次握手的确认,服务器端无法确定客户端是否成功接收到SYN-ACK包,并且无法发送ACK包。因此,客户端和服务器端都处于等待状态,形成了死锁。
死锁情况二(服务器端发起连接失败):服务器端发送SYN-ACK包给客户端,但由于网络延迟或其他原因,客户端没有收到该包。此时,服务器端认为连接已经建立,进入等待状态,而客户端并不知道服务器端的存在。由于缺乏第三次握手的ACK确认,客户端无法确定服务器端是否成功接收到ACK包,并且无法发送数据。因此,客户端和服务器端都处于等待状态,形成了死锁。
在这两种情况下,由于缺乏第三次握手的确认,双方无法确定连接是否成功建立,进入了死锁状态。为了避免这种情况,TCP协议采用了三次握手的机制,确保双方都能够正常通信并建立可靠的连接。
tcp的四次挥手
四次挥手是TCP协议中关闭连接的过程。在双方通信结束后,需要通过四次挥手来正常关闭连接,确保双方都能够完成数据的传输并释放相关资源。下面是四次挥手的详细步骤:
-
第一次挥手(FIN):当一个端口(通常是客户端)确定不再发送数据时,它会发送一个FIN(结束)包给另一个端口(通常是服务器端)。这个FIN包表示它已经完成了数据的发送。
-
第二次挥手(ACK):接收到FIN包的端口(通常是服务器端)会发送一个ACK(确认)包给对方,表示已经收到了FIN包。此时,服务器端进入半关闭状态,即不再接收来自客户端的数据,但仍可以向客户端发送数据。
-
第三次挥手(FIN):当另一个端口(通常是服务器端)也确定不再发送数据时,它会发送一个FIN包给另一个端口(通常是客户端)。这个FIN包表示它已经完成了数据的发送。
-
第四次挥手(ACK):接收到FIN包的端口(通常是客户端)会发送一个ACK包给对方,表示已经收到了FIN包。此时,客户端进入TIME_WAIT状态,等待一段时间后关闭连接,确保服务器端收到了ACK包。
完成了这四次挥手之后,双方都完成了数据的传输并释放了相关资源,连接被正常关闭。
四次挥手的目的是确保双方都能够完成数据的传输并释放相关资源。通过四次挥手,双方可以协商关闭连接,并确保对方收到了关闭连接的请求。这样可以避免数据的丢失或不完整,并且保证连接的可靠关闭。
补充:
TIME_WAIT状态的主要目的是确保在网络中所有的数据包都已经被接收和处理完毕,以避免数据的重复传输或混乱。在TIME_WAIT状态下,端口会保持开放并等待一段时间(通常是2倍的最大报文段生存时间(MSL)),以确保网络中已经没有挂起的数据包。
tcp的长连接和短连接
TCP 在真正的读写操作之前,server 与 client 之间必须建立一个连接,
当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,
连接的建立通过三次握手,释放则需要四次握手,
所以说每个连接的建立都是需要资源消耗和时间消耗的。
通信的全程图
短连接和长连接的区别
短链接实际上就是在通信的过程中只进行一次send和recv,而长连接进行多次
短链接的操作步骤:
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
长连接的操作步骤:
建立连接——数据传输…(保持连接)…数据传输——关闭连接
TCP 长/短连接的优点和缺点
- 长连接可以省去较多的 TCP 建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。
- client 与 server 之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server 早晚有扛不住的时候,这时候 server 端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server 端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。
- 短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在 TCP 的建立和关闭操作上浪费时间和带宽。
TCP 长/短连接的应用场景
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个 TCP 连接都需要三次握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,再次处理时直接发送数据包就 OK 了,不用建立 TCP 连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成 socket 错误,而且频繁的 socket 创建也是对资源的浪费。
而像 WEB 网站的 http 服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像 WEB 网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。
相关文章:

7 网络通信(上)
文章目录 网络通信概述ip地址ip的作用ip地址的分类私有ip 掩码和广播地址 linux 命令(ping ifconfig)查看或配置网卡信息:ifconfig(widows 用ipconfig)测试远程主机连通性:ping路由查看 端口端口是怎样分配的知名端口动态端口 查看…...
MFC图表控件high-speed-charting的使用
high-speed-charting是MFC上的开源图表库,Teechart的替代品。 high-speed-charting的下载地址 https://www.codeproject.com/Articles/14075/High-speed-Charting-Control 特性 High-speed drawing (when axis is fixed) which allows fast plotting of dataUnlimited number …...
Unity中常用方法
1.基础 //初始化引入 [RequireComponent(typeof(BoxCollider2D))] [RequireComponent(typeof(Rigidbody2D))]//游戏帧率设置 60帧Application.targetFrameRate 60;//获取物体对象 //获取到当前物体(根据名称,也可以根据路径)GameObject go GameObject.Find("…...

【监控系统】可视化工具Grafana简介及容器化部署实战
1.什么是Grafana 官网地址:https://grafana.com/ Grafana用Go语言开发的开源数据可视化工具,可以做数据监控和数据统计,带有告警功能。支持快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中…...

VUE之VueRouter页面跳转
参考资料: 参考视频 参考demo及视频资料 VUE之基本部署及VScode常用插件 VUE之基本组成和使用 VUE之Bootstrap和Element-UI的使用 VUE之axios使用,跨域问题,拦截器添加Token Vue Router官网 Vue Router说明: 说明…...

【188】Java8利用AVL树实现Map
AVL树又被叫做平衡二叉搜索树、平衡二叉树。AVL是其发明者的首字母缩写。 这篇文章中,AVLTreeMap 类集成了 java.util.Map 接口,并利用 AVL 树结构实现了 Map 接口的所有方法。本文还给出了测试代码。 为什么要发明AVL树? 当我按照从小到大…...
[SQL挖掘机] - 右连接: right join
介绍: 右连接是一种多表连接方式,它以右侧的表为基础,并返回满足连接条件的匹配行以及右侧表中的所有行,即使左侧的表中没有匹配的行。右连接将右表的每一行与左表进行比较,并根据连接条件返回结果集。其实, 左连接和右连接原理一…...
bug篇之基于docker安装nacos(2.1.1)使用dubbo连接不上的问题
说明:首先我的nacos安装是2.1.1版本,请注意版本问题。另外启动时用dubbo的话必须先启动服务提供者再启动服务使用者,否则会报错,同时也必须开放三个端口:8848,9848,9849 java.lang.IllegalStat…...
【Python入门系列】第二十一篇:Python物联网和传感器应用
文章目录 前言一、Python在物联网和传感器应用中的优势二、连接传感器和设备三、读取传感器数据四、示例代码和讲解五、进一步处理和分析传感器数据六、更多应用示例1、温湿度监测系统2、智能家居系统 - 灯光控制 总结 前言 物联网和传感器在现代科技中扮演着重要的角色。物联…...

Python爬虫的urlib的学习(学习于b站尚硅谷)
目录 一、页面结构的介绍 1.学习目标 2.为什么要了解页面(html) 3. html中的标签(仅介绍了含表格、无序列表、有序列表、超链接) 4.本节的演示 二、Urllib 1.什么是互联网爬虫? 2.爬虫核心 3.爬虫…...
【MongoDB】--MongoDB聚合Aggregation
目录 一、前言二、聚合管道操作2.1、实际案例1(1)、案例--根据学生no,找到对应班级名称(2)、案例--这个班级有哪些学生和哪些老师在任课 2.2、实际案例2(1)、案例--主表和关联表都有条件限制,且分页返回 一、前言 聚合操作组值来自多个文档,…...

Hadoop学习指南:探索大数据时代的重要组成——Hadoop概述
前言 在当今大数据时代,处理海量数据成为了一项关键任务。Hadoop作为一种开源的分布式计算框架,为大规模数据处理和存储提供了强大的解决方案。本文将介绍Hadoop的组成和其在大数据处理中的重要作用,让我们一同踏上学习Hadoop的旅程。 Hado…...

Java实现简单小画板
Java制作简单画板,包括两个类,一个主要画板类Drawpad,一个画板监听器DrawListener类。 1、Drawpad类,包括画板,画板功能设计,保存图片等 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 2…...

B078-项目实战--支付模块 领养订单支付流程
目录 支付模块需求分析表设计支付单表支付宝账号信息表-商家账号微信支付账号信息表-商家账号银行账号表-商家资金账号表支付流水表 流程分析支付基础模块继承加密算法沙箱环境准备支付宝支付-流程分析根据demo封装工具类导入依赖AlipayConfigAlipayInfoAlipayUtil 内网穿透 领…...

[css]margin-top不起作用问题(外边距合并)
在初学css时,会遇到突然间margin-top不起作用的情况。如下面: 情况一: 代码: <html> <head><style type"text/css"> * {margin:0;padding:0;border:0; }#outer {width:300px;height:300px;backgroun…...

Vue2基础八、插槽
零、文章目录 Vue2基础八、插槽 1、插槽 (1)默认插槽 作用:让组件内部的一些 结构 支持 自定义需求: 将需要多次显示的对话框, 封装成一个组件问题:组件的内容部分,不希望写死,希望能使用的时候自定义。…...
自然语言处理从入门到应用——LangChain:提示(Prompts)-[提示模板:连接到特征存储]
分类目录:《自然语言处理从入门到应用》总目录 特征存储是传统机器学习中的一个概念,它确保输入模型的数据是最新和相关的。在考虑将LLM应用程序投入生产时,这个概念非常重要。为了个性化LLM应用程序,我们可能希望将LLM与特定用户…...

jenkins自定义邮件发送人姓名
jenkins发送邮件的时候发送人姓名默认的,如果要自定义发件人姓名,只需要修改如下信息即可: 系统管理-system-Jenkins Location下的系统管理员邮件地址 格式为:自定义姓名<邮件地址>...

SolidWorks二次开发---简单的连接solidworks
创建一个.net Framework的应用,正常4.0以上就可以了。 打开nuget包管理 在里面搜索paine 在版中选择对应的solidworks年份开头的,进行安装。 安装完之后 : 同时选中下面两个dll,把嵌入操作类型改为false 然后在按钮的单击事件中输入: Connect.Crea…...
docker 安装 active Mq
在安装完Docker的机器上,安装activeMQ。 拉取镜像: docker pull webcenter/activemq 查看镜像: docker images Docker运行ActiveMQ镜像 docker run --name activemq -d -p 8161:8161 -p 61616:61616 --privilegedtrue --restartalways …...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...