1. 如何强行关闭客户端和服务器之间的连接?
在网络编程中,有时需要强行中断客户端和服务器之间的连接。对于基于 TCP 协议的连接,由于其面向连接的特性,需要采取特定的步骤来确保连接被正确关闭;而 UDP 是无连接协议,处理方式相对简单。
服务器端(TCP)
python
import socket
# 创建 TCP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_socket.bind(('localhost', 8888))
# 开始监听
server_socket.listen(1)
print("Waiting for a connection...")
# 接受客户端连接
conn, addr = server_socket.accept()
print(f"Connected by {addr}")
try:
# 强制关闭连接
# 先禁用读写
conn.shutdown(socket.SHUT_RDWR)
# 关闭连接
conn.close()
print("Connection closed.")
except Exception as e:
print(f"Error closing connection: {e}")
客户端(TCP)
python
import socket
# 创建 TCP 套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
client_socket.connect(('localhost', 8888))
try:
# 强制关闭连接
client_socket.shutdown(socket.SHUT_RDWR)
client_socket.close()
print("Connection closed.")
except Exception as e:
print(f"Error closing connection: {e}")
服务器端(UDP)
python
import socket
# 创建 UDP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定地址和端口
server_socket.bind(('localhost', 8888))
try:
# 停止接收数据并关闭套接字
server_socket.close()
print("UDP socket closed.")
except Exception as e:
print(f"Error closing UDP socket: {e}")
- 要点
- TCP 连接关闭需要先使用
shutdown
方法禁用读写,再调用close
方法关闭连接。 - UDP 连接直接调用
close
方法关闭套接字。 - 在实际应用中,强行关闭连接可能会导致数据丢失或未完成的操作中断。因此,在关闭连接之前,最好确保所有必要的数据已经传输完成。另外,对于 TCP 连接,
shutdown
方法可以指定不同的参数,如socket.SHUT_RD
表示关闭读通道,socket.SHUT_WR
表示关闭写通道。
2. 说明 TCP 和 UDP 的区别以及优缺点
TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是两种常见的传输层协议,它们在连接性、可靠性、有序性、传输效率和首部开销等方面存在明显差异。
python
import socket
# TCP 服务器示例
def tcp_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8888))
server_socket.listen(1)
print("TCP server is listening...")
conn, addr = server_socket.accept()
data = conn.recv(1024)
print(f"Received from {addr}: {data.decode()}")
conn.close()
# UDP 服务器示例
def udp_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('localhost', 8889))
print("UDP server is listening...")
data, addr = server_socket.recvfrom(1024)
print(f"Received from {addr}: {data.decode()}")
server_socket.close()
if __name__ == "__main__":
import threading
tcp_thread = threading.Thread(target=tcp_server)
udp_thread = threading.Thread(target=udp_server)
tcp_thread.start()
udp_thread.start()
- 要点
对比项 | TCP | UDP |
---|---|---|
连接性 | 面向连接,需三次握手建立连接,四次挥手断开连接 | 无连接,直接发送数据 |
可靠性 | 提供可靠传输,有确认、重传、滑动窗口机制 | 不可靠,可能丢包、乱序 |
有序性 | 保证数据有序接收 | 不保证数据有序 |
传输效率 | 相对较低,有连接建立和断开开销 | 相对较高,无连接开销 |
首部开销 | 一般为 20 字节 | 固定为 8 字节 |
优点 | 可靠、有序,适用于文件传输、网页浏览 | 高效、开销小,适用于实时性要求高的场景 |
缺点 | 效率低、资源占用多 | 不可靠、不保证有序 |
在选择使用 TCP 还是 UDP 时,需要根据具体的应用场景来决定。例如,对于视频会议、在线游戏等对实时性要求较高的应用,即使可能会有少量数据丢失,也更适合使用 UDP;而对于文件下载、电子邮件等对数据准确性要求较高的应用,则应选择 TCP。
3. 简述浏览器通过 WSGI 请求动态资源的过程
WSGI(Web Server Gateway Interface)是 Python Web 应用程序和 Web 服务器之间的标准接口,它定义了 Web 服务器如何与 Python 应用程序进行通信。浏览器通过 WSGI 请求动态资源的过程涉及多个环节。
python
def simple_app(environ, start_response):
"""简单的 WSGI 应用"""
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
return [b'Hello, World!']
if __name__ == '__main__':
from wsgiref.simple_server import make_server
httpd = make_server('localhost', 8000, simple_app)
print("Serving on port 8000...")
httpd.serve_forever()
- 要点
-
浏览器发起 HTTP 请求。
-
Web 服务器(如 Apache、Nginx)接收请求。
-
Web 服务器将请求信息封装成符合 WSGI 规范的环境变量和可调用对象,调用 WSGI 应用程序。
-
WSGI 应用程序处理请求,可能访问数据库、调用其他服务。
-
WSGI 应用程序返回响应信息。
-
Web 服务器将响应信息封装成 HTTP 响应,发送给浏览器。
-
浏览器解析渲染页面。
WSGI 使得 Python Web 应用程序可以在不同的 Web 服务器上运行,提高了代码的可移植性。常见的 Python Web 框架如 Flask、Django 都遵循 WSGI 规范。
4. 说明浏览器访问 www.baidu.com 的过程
当用户在浏览器中输入 www.baidu.com
并回车后,浏览器会经历一系列步骤来获取并显示百度的网页。
python
import socket
try:
ip = socket.gethostbyname('www.baidu.com')
print(f"The IP address of www.baidu.com is {ip}")
except socket.gaierror as e:
print(f"DNS resolution error: {e}")
- 要点
-
DNS 解析:浏览器先检查本地 DNS 缓存,若没有则向本地 DNS 服务器查询,本地 DNS 服务器若没有则逐级向根 DNS 服务器、顶级域名 DNS 服务器、权威 DNS 服务器查询,最终获取目标网站的 IP 地址。
-
TCP 连接:使用获取到的 IP 地址和端口号(通常是 80 或 443),通过三次握手与服务器建立 TCP 连接。
-
HTTP 请求:浏览器向服务器发送 HTTP 请求,包含请求方法、URL、请求头和请求体。
-
服务器处理请求:服务器根据请求内容进行处理,可能涉及数据库查询、应用程序调用等。
-
HTTP 响应:服务器处理完请求后,向浏览器发送 HTTP 响应,包含响应状态码、响应头和响应体。
-
浏览器解析渲染页面:浏览器解析响应内容,构建 DOM 树、CSSOM 树,合并成渲染树,进行布局和绘制。
-
TCP 连接关闭:页面渲染完成后,通过四次挥手关闭 TCP 连接。
在实际过程中,还可能涉及到 HTTPS 协议的加密和解密过程,以及缓存策略的应用,以提高访问速度和性能。
5. 说明Post 和 Get 请求的区别
Post 和 Get 是 HTTP 协议中常用的两种请求方法,它们在参数传递方式、安全性、数据长度限制、缓存和使用场景等方面存在差异。
python
import requests
# Get 请求示例
response_get = requests.get('https://www.example.com', params={'key': 'value'})
print(f"Get response status code: {response_get.status_code}")
# Post 请求示例
data = {'key': 'value'}
response_post = requests.post('https://www.example.com', data=data)
print(f"Post response status code: {response_post.status_code}")
- 要点
对比项 | Get | Post |
---|---|---|
参数传递方式 | 参数附加在 URL 后面 | 参数放在请求体中 |
安全性 | 参数暴露在 URL 中,不安全 | 参数在请求体中,相对安全 |
数据长度限制 | URL 长度有限制 | 无数据长度限制 |
缓存 | 会被浏览器缓存 | 一般不会被缓存 |
使用场景 | 适用于获取数据 | 适用于提交数据 |
在实际开发中,需要根据具体的需求选择合适的请求方法。同时,对于敏感信息的传递,即使使用 Post 请求,也建议采用 HTTPS 协议进行加密传输。
6. 说明cookie 和 session 的区别
Cookie 和 Session 是 Web 开发中用于跟踪用户状态的两种机制,它们在存储位置、安全性、数据大小、有效期和应用场景等方面有所不同。
python
from flask import Flask, request, make_response, session
app = Flask(__name__)
app.secret_key = 'your_secret_key'
@app.route('/set_cookie')
def set_cookie():
resp = make_response('Setting cookie...')
resp.set_cookie('username', 'John')
return resp
@app.route('/get_cookie')
def get_cookie():
username = request.cookies.get('username')
return f'Cookie username: {username}'
@app.route('/set_session')
def set_session():
session['user'] = 'John'
return 'Setting session...'
@app.route('/get_session')
def get_session():
user = session.get('user')
return f'Session user: {user}'
if __name__ == '__main__':
app.run(debug=True)
- 要点
对比项 | Cookie | Session |
---|---|---|
存储位置 | 客户端浏览器 | 服务器端 |
安全性 | 不安全,可能被分析和欺骗 | 相对安全,数据在服务器端 |
数据大小 | 单个 Cookie 不超过 4K,一个站点最多保存 20 个 | 无数据大小限制 |
有效期 | 可通过 | 默认浏览器关闭失效,可设置延长 |
应用场景 | 保存基本信息,如用户名、偏好设置 | 保存登录状态、购物车信息 |
在使用 Cookie 和 Session 时,需要注意安全性问题。对于 Cookie,可以设置 HttpOnly
和 Secure
属性来提高安全性;对于 Session,需要对会话 ID 进行加密和管理,防止会话劫持。
7. HTTP 协议有哪些状态码
HTTP 状态码是服务器返回给客户端的三位数字代码,用于表示请求的结果。常见的状态码可以分为五类。
python
import requests
response = requests.get('https://www.example.com')
print(f"Response status code: {response.status_code}")
- 要点
状态码分类 | 含义 | 常见状态码及说明 |
---|---|---|
1xx(信息性状态码) | 表示临时响应,用于通知客户端部分请求已被接收 | 100 Continue:客户端应继续发送请求 |
2xx(成功状态码) | 表示请求成功 | 200 OK:请求成功;201 Created:资源已创建;204 No Content:请求成功但无返回内容 |
3xx(重定向状态码) | 表示需要进一步操作以完成请求 | 301 Moved Permanently:资源永久移动;302 Found:资源临时移动;304 Not Modified:资源未修改,可使用缓存 |
4xx(客户端错误状态码) | 表示客户端请求有错误 | 400 Bad Request:请求语法错误;401 Unauthorized:未授权;403 Forbidden:服务器拒绝执行;404 Not Found:资源不存在 |
5xx(服务器错误状态码) | 表示服务器处理请求时出现错误 | 500 Internal Server Error:服务器内部错误;502 Bad Gateway:网关或代理接收到无效响应;503 Service Unavailable:服务器临时不可用 |
在实际开发中,根据不同的状态码可以进行相应的处理。例如,当返回 404 状态码时,可以显示自定义的错误页面;当返回 500 状态码时,需要记录错误日志以便排查问题。
8. 什么是三次握手和四次挥手
三次握手是 TCP 建立连接的过程,确保双方都有发送和接收数据的能力;四次挥手是 TCP 断开连接的过程,确保双方都能正确关闭连接。
python
# 模拟三次握手
def three_way_handshake():
print("Client: SYN, seq=x")
print("Server: SYN+ACK, seq=y, ack=x+1")
print("Client: ACK, ack=y+1")
print("Connection established.")
# 模拟四次挥手
def four_way_wave():
print("Client: FIN, seq=u")
print("Server: ACK, ack=u+1")
print("Server: FIN, seq=v")
print("Client: ACK, ack=v+1")
print("Connection closed.")
if __name__ == "__main__":
print("Three-way handshake:")
three_way_handshake()
print("\nFour-way wave:")
four_way_wave()
- 要点
三次握手:
-
客户端发送 SYN 包,请求建立连接。
-
服务器发送 SYN+ACK 包,同意建立连接并确认客户端请求。
-
客户端发送 ACK 包,确认服务器请求,连接建立。
四次挥手:
-
客户端发送 FIN 包,请求关闭连接。
-
服务器发送 ACK 包,确认客户端关闭请求。
-
服务器发送 FIN 包,请求关闭连接。
-
客户端发送 ACK 包,确认服务器关闭请求,连接断开。
三次握手和四次挥手是 TCP 协议保证连接可靠性的重要机制。在实际网络环境中,可能会出现丢包、超时等情况,需要通过重传机制来确保连接的正常建立和关闭。
9. 什么是 TCP 的 2MSL
MSL(Maximum Segment Lifetime)是指一个 TCP 分段在网络中最大的生存时间。2MSL 即两倍的 MSL 时间。在 TCP 连接关闭过程中,主动关闭连接的一方在发送最后一个 ACK 包后,会进入 TIME - WAIT 状态并保持 2MSL 时间。
python
# 模拟 TCP 连接关闭进入 TIME - WAIT 状态
def tcp_connection_close():
print("Client sends FIN to close connection.")
print("Server sends ACK.")
print("Server sends FIN.")
print("Client sends ACK and enters TIME - WAIT state for 2MSL.")
if __name__ == "__main__":
tcp_connection_close()
- 要点
-
MSL 是 TCP 分段在网络中的最大生存时间。
-
2MSL 是主动关闭连接方在 TIME - WAIT 状态的停留时间。
不同的操作系统对 MSL 的定义可能不同,一般来说,MSL 的值在 30 秒到 2 分钟之间。2MSL 时间的设置是为了保证 TCP 连接的可靠
友情提示:本文已经整理成文档,可以到如下链接免积分下载阅读
https://download.csdn.net/download/ylfhpy/90411385