当前位置: 首页 > news >正文

全国购网站建设外链代发免费

全国购网站建设,外链代发免费,在哪里建设网站,拖拽建站平台6. TCP 三次握手四次挥手 HTTP 协议是 Hype Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器(sever)传输超文本到客户端(本地浏览器…

6. TCP 三次握手四次挥手

HTTP 协议是 Hype Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器(sever)传输超文本到客户端(本地浏览器 client)的传送协议。HTTP 协议基于 TCP/IP 协议之上,HTTPS 基于 TLS/SSL 协议层上,两者都是属于应用层的面向对象的协议。

由上图可知,HTTP 协议工作前需要 client 与 sever 建立连接。该连接由 tcp 来完成,tcp 与 ip 共同组成了 Internet,也就是著名的 TCP/IP 通信协议。

6.1 TCP 简介

TCP(Transmission Control Protocol)全名传输控制协议,是主机对住几层的传输控制协议,提供可靠的连接服务,采用三次握手来建立一个连接。与 UDP 都是传输层的协议,比 UDP 更可靠,默认端口 80 。

TCP标志位(位码):

  • SYN(synchronous):建立连接
  • ACK(acknowledgement):确认
  • ack:确认号
  • PSH(push):传送
  • FIN(finish):结束
  • RST(reset):重置
  • URG(urgent):紧急
  • Sequence number:顺序号码
  • Acknowledge number:确认号码

6.2 三次握手

最初两端 TCP 进程都处于关闭状态,client 主动打开连接,server 被动打开连接。大致步骤:client、server 关闭 —— server 收听到 listen —— client 同步已发送状态 SYN-SENT —— server 同步收到状态 SYN_RCVD —— client、server 已建立状态 ESTABLEISHED。

规定:SYN=1 的报文不传输数据,并消耗一个随机序列号。

1、第一次

client 向 server 发送连接请求报文 SYN=1 ,同时生成初始序列化 seq=x,此时 client 进入 SYN-SENT(同步已发送)状态。

2、第二次

server 收到请求报文后,如果同意连接,则发出确认报文。确认报文中包含:ACK=1,SYN=1,确认号:ack=x+1(即上一次的seq+1),同时也要为自己随机初始化一个序列号 seq=y。此时 server 进入 SYN-RCVD(同步收到)状态。这个报文也没有携带数据,循环 client 是否准备好。

3、第三次

client 收到确认后,向 server 给出确认:ACK=1(与 server 给出的一致),ack=y+1,此时 client 连接建立,进入 ESTABLISHED 状态。这里客户端表示已经准备好了。

6.3 四次挥手

1、第一次

client 发送一个 FIN ,用来结束连接。client 进程发出连接释放报文,并停止发送数据。释放报文首部:FIN=1,序列号 seq=i

此时 client 进入 FIN_WAIT_1 (终止等待1)状态。

2、第二次

server 收到这个 FIN 后,返回一个 ACK(确认),确认序号:ack=i+1。同时携带自己的序列号 seq=j

此时, server 进入 CLOSED_WAIT(关闭等待)状态。

并通知高层的应用进程,此时处于半关闭状态,client 没有数据发送了,但 server 若发送数据,client 依然会接收,这种状态还会持续一段时间。

3、第三次

server 将最后的数据发送完毕后,发送一个 FIN(结束),确认序号:ack=i+1,同时携带序号 seq=w,准备 关闭 client 的连接,等待 client 的最后确认。

此时,server 进入 LAST_ACK(最后确认)状态。

4、第四次

client 发送 ACK 确认,并将确认序号+1:ack=w+1,而自己序列号 seq=i+1

此时,client 进入 TIME_WAIT(时间等待)状态。

**Note:**此时 client 并没有释放,必须等待 2MSL(最长报文段寿命)使君子后,当 server 撤销相应 TCB 后,从进入 CLOSED 状态。server 只要收到了 client 发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接

为什么会是四次挥手?

三次握手时没有数据传输,而四次挥手时涉及到有数据传输。client 发出关闭请求,表示已经数据传输完毕,但是 server 有可能数据还未传输完毕,这时就需要已 server 端数据是否传输完毕为标准,因此需要四次。

当高并发时,现实情况往往是 server 先断开 client 连接,因为多保存 client 一次连接,就会多占用一些资源。因此在短时间内再次向 server 发起连接,会提示 serve time_wait。

客户端突然挂掉了怎么办?

正常连接时,客户端突然挂掉了,如果没有措施处理这种情况,那么就会出现客户端和服务器端出现长时期的空闲。解决办法是在服务器端设置保活计时器,每当服务器收到

客户端的消息,就将计时器复位。超时时间通常设置为2小时。若服务器超过2小时没收到客户的信息,他就发送探测报文段。若发送了10个探测报文段,每一个相隔75秒,

还没有响应就认为客户端出了故障,因而终止该连接。

参考文章:https://www.cnblogs.com/qdhxhz/p/8470997.html

7. 客户端服务端循环发送信息

之前设计的 socket 程序只能进行一次发送接收就终止掉了,而现实情况不可能只有一次发送与接收,往往都是循环往复,那么就需要给 socket client 和 socket server 添加循环机制。

服务端:

from socket import *ip_port = ('127.0.0.1', 8000)
back_log = 5
buffer_size = 1024tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)print('服务端开始运行')
conn, addr = tcp_server.accept()while True:data = conn.recv(buffer_size)print('客户端发来的信息是', data.decode('utf-8'))conn.send(data.upper())conn.close()
tcp_server.close()
服务端开始运行
客户端发来的信息是 python

客户端:

from socket import *ip_port = ('127.0.0.1', 8000)
buffer_size = 1024tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)     # 连接服务端while True:msg = input('请输入要发送的信息:')tcp_client.send(msg.encode('utf-8'))print('---------客户端已经发送消息------------')data = tcp_client.recv(buffer_size)print('接收到服务端发来的信息', data.decode('utf-8'))tcp_client.close()
请输入要发送的信息:python
---------客户端已经发送消息------------
接收到服务端发来的信息 PYTHON
请输入要发送的信息:

8. socket 收发信息原理剖析

socket 客户端和服务端都属于应用层,即用户态层面。它们产生的数据(或从客户端发送到服务端的数据)必须通过内核态调用操作系统,将数据 copy 到内存中(缓存),然后根据 TCP/UDP 协议、通过网卡、Internet 传输到服务端。

服务端再通过内核态从缓存中取出数据。收发消息会在缓存中形成一个消息队列,遵循 先进先出原则,后面进来的消息后处理。

操作系统的体系架构分为 用户态和内核态,内核从本质上讲也一种软件 —— 控制计算机的硬件资源,并提供上层应用程序运行的环境。

用户态即上层应用程序的活动空间,应用程序的执行必须依托内核提供的资源,包括(CPU、存储、I/O资源等)。为了使用户态能访问这些资源,内核必须为上层应用提供访问的接口 —— 系统调用(系统调用是操作系统的最小单位)。

9. 服务端循环连接请求来接收信息

9.1 当用户输入为空或直接回车时

当用户在 client 端输入为空,或直接输入回车时,client 端与 server 端都开在接收信息处。这是因为 client 端没有真正的信息(0 字节)发送给 server 端,因此 server 端就不会有信息回复。

解决办法:在 client 端对用户输入的信息进行判断即可

if not msg:continue		# 如果输入信息为空,那么继续输入

9.2 当 client 端异常断开时

当我们直接断开 client 的连接,而非四次挥手时正常断开,发现 server 直接报如下错误:

ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

现实情况中,不可能一个 client 端每次不正常断开连接,就导致 server 端直接断开。那么其他的 client 就不能连接 server。

解决办法:对 server 端信息接收处使用异常处理

while True:try:data = conn.recv(buffer_size)print('客户端发来的信息是', data.decode('utf-8'))conn.send(data.upper())except Exception:break

这样不论 client 端是怎么断开的,都不会导致 server 端断开。

9.3 当有多个 client 发起连接时

当有多个 client 发起连接时,遵循 先进先出 原则。先连接的 client ,先处理,后发起连接的 client 会被存储到 back_log 中。back_log 为链接监听(listen)的最大数目。

每次只能处理一天连接,当处理完毕后就会直接关闭连接,也就是说只能服务一个 client,我们希望的是 server 端能够循环提供服务,显然这不是我们想要的结果。

解决办法:对被动接受 client 的连接处进行循环(即 accept)

服务端:

from socket import *# 获取主机名
host = gethostname()
# 端口号
port = 8080back_log = 5
buffer_size = 1024tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind((host, port))
tcp_server.listen(back_log)while True:			# 循环接收 client 发起的连接print('服务端开始运行')print(host)conn, addr = tcp_server.accept()while True:		# 循环接收 client 发来的信息,以及发送信息给 client try:		# 对 client 的异常断开进行异常处理data = conn.recv(buffer_size)print('客户端发来的信息是', data.decode('utf-8'))conn.send(data.upper())except Exception:breakconn.close()
tcp_server.close()

客户端:

from socket import *# 获取主机名
host = gethostname()
# 端口号
port = 8080buffer_size = 1024tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect((host, port))     # 连接服务端while True:msg = input('请输入要发送的信息:').strip()if not msg: continue	# 对用户输入的信息进行判断tcp_client.send(msg.encode('utf-8'))print('---------客户端已经发送消息------------')data = tcp_client.recv(buffer_size)print('接收到服务端发来的信息', data.decode('utf-8'))tcp_client.close()

9.5 总结

要想 client 与 server 能够自由交互数据,并且 server 能循环提供服务,需要满足如下条件:

  • 需要对用户输入的数据进行判断
  • server 能够处理 client 异常断开时的情况
  • server 要能够循环接收 client 发起的连接

10. socket 函数

1. 服务端套接字函数

  • s.bind():绑定(主机,端口号)到套接字,元组形式
  • s.listen():开始 TCP 监听
  • s.accept():被动接受 TCP 客户的连接,(阻塞式)等待连接的到来。

2. 客户端套接字函数

  • s.connect():主动初始化 TCP 服务器连接
  • s.connect_ex():connect()函数的拓展版本,出错时返回出错码,而不是抛出异常

3. 公共用途套接字函数

  • s.recv():接受 TCP 数据
  • s.send():发送 TCP 数据(send 在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
  • s.sendall():发送完整的 TCP 数据(本质就是循环调用 send,sendall 在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用 send 直到发完。)
  • s.recvfrom():接收 UDP 数据
  • s.sendto():发送 UDP数据
  • s.getpeername():连接到当前套接字的远端的地址
  • s.getsockname():当前套接字的地址
  • s.getsockopt():返回指定套接字的参数
  • s.setsockopt():设置指定套接字的参数
  • s.close():关闭套接字

面向锁的套接字函数

  • s.setblocking():设置套接字的阻塞与非阻塞模式
  • s.settimeout():设置阻塞套接字操作的超时时间
  • s.gettimeout():得到阻塞套接字操作的超时时间

面向文件的套接字的函数

  • s.fileno():套接字的文件描述符
  • s.makefile():创建一个与该套接字相关的文件

**Tips:**send 一次最大数据最好控制在 8 k 左右,为了避免超过内存大小,可以使用 sendall 方法。其本质是在循环调用 send 方法。

http://www.tj-hxxt.cn/news/15743.html

相关文章:

  • 做胃肠医院网站seo优化技术培训
  • 做问卷调查赚钱网站好台州百度关键词排名
  • 临沂做网站的公司搜索引擎优化策略不包括
  • 网站建设 地址: 上海石门二路网站排名首页前三位
  • 企业买好域名后怎么做网站搜索引擎seo
  • 杭州 电子商务网站建设如何提升网站seo排名
  • 打开传奇sf网站做是一个网站百度指数移动版怎么用
  • 做博彩网站判刑多少年宁波营销型网站建设优化建站
  • 容桂销售型网站建设网页优化方法
  • 日本做的视频网站有哪些问题网络营销的应用
  • 手机wap网站开发的cms系统一键优化是什么意思
  • 行政单位单位网站建设十堰seo优化
  • 蓬莱网站建设哪家好淘特app推广代理
  • 什么网站做生鲜比较好网络营销的职能是什么
  • 处方药可以做网站吗莆田seo
  • 金融营销的网站设计案例免费有效的推广网站
  • 个人网站logo设计响应式网站模板的特点
  • 做国际网站的流程admin5站长网
  • 南京高端网站制作公司哪家好seo优化信
  • 提供邯郸企业建网站深圳广告策划公司
  • 赤峰网站建设百度知道灰色词代发收录
  • 连云港疫情最新消息在线seo优化工具
  • go做网站白百度一下你就知道
  • 无锡市新区建设环保局网站电话营销外包公司
  • 云南省公共资源交易中心官网seo的课谁讲的好
  • 手机网站建立免费平台什么是软文写作
  • php做购物网站的弊端关键字挖掘机爱站网
  • 佛山网站建设小程序北京seo技术交流
  • webstation做网站建站公司排名
  • 有哪些好的印花图案设计网站sem是什么基团