- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我已经对两个服务器进行了编程,它们基本上使用不同的方法执行相同的操作。两者都是网络服务器,在套接字对象周围有一个非阻塞的 ssl 包装器。线程允许同时处理多个请求。
一个使用 ThreadingTCPServer,另一个调用 HTTPServer 模块上的 ThreadingMixIn。我应该使用哪一个,为什么其中一个比另一个更好?
HTTPServer 上的 ThreadingMixIn:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, ssl
from socketserver import ThreadingMixIn
from http.server import SimpleHTTPRequestHandler, HTTPServer
MYSERV_WORKDIR = "/media/kingdian/server_pub"
#MYSERV_CLIENTCRT = "/home/ran/keys/client.pem"
MYSERV_FULLCHAIN = "/home/ran/.acme.sh/example.com_ecc/fullchain.cer"
MYSERV_PRIVKEY = "/home/ran/.acme.sh/example.com_ecc/example.com.key"
global sslcontext
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
sslcontext.options |= ssl.OP_NO_TLSv1
sslcontext.options |= ssl.OP_NO_TLSv1_1
#sslcontext.options |= ssl.OP_NO_TLSv1_2
#sslcontext.protocol = ssl.PROTOCOL_TLS
#sslcontext.verify_mode = ssl.CERT_REQUIRED
sslcontext.set_ciphers("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305")
sslcontext.set_ecdh_curve("secp384r1")
#sslcontext.load_verify_locations(MYSERV_CLIENTCRT)
sslcontext.load_cert_chain(MYSERV_FULLCHAIN, MYSERV_PRIVKEY)
class HSTSHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload")
self.send_header("Content-Security-Policy", "default-src 'self'")
self.send_header("X-Content-Type-Options", "nosniff")
self.send_header("X-Frame-Options", "SAMEORIGIN")
self.send_header("X-XSS-Protection", "1; mode=block")
self.send_header("Referrer-Policy", "no-referrer")
SimpleHTTPRequestHandler.end_headers(self)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
daemon_threads = True
def main():
try:
os.chdir(MYSERV_WORKDIR)#auto-change working directory
SimpleHTTPRequestHandler.sys_version = "002"#display custom Python system version
SimpleHTTPRequestHandler.server_version = "001"#display custom server software version
my_server = ThreadedHTTPServer(('', 443), HSTSHandler)
my_server.socket = sslcontext.wrap_socket(my_server.socket, do_handshake_on_connect=False, server_side=True)
print('Starting server, use <Ctrl-C> to stop')
my_server.serve_forever()
except KeyboardInterrupt:
print(' received, shutting down server')
my_server.shutdown()
if __name__ == '__main__':
main()
线程TCP服务器:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, ssl, socketserver
from http.server import SimpleHTTPRequestHandler
MYSERV_WORKDIR = "/media/kingdian/server_pub"
#MYSERV_CLIENTCRT = "/home/ran/keys/client.pem"
MYSERV_FULLCHAIN = "/home/ran/.acme.sh/example.com_ecc/fullchain.cer"
MYSERV_PRIVKEY = "/home/ran/.acme.sh/example.com_ecc/example.com.key"
global sslcontext
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
sslcontext.options |= ssl.OP_NO_TLSv1
sslcontext.options |= ssl.OP_NO_TLSv1_1
#sslcontext.options |= ssl.OP_NO_TLSv1_2
#sslcontext.protocol = ssl.PROTOCOL_TLS
#sslcontext.verify_mode = ssl.CERT_REQUIRED
sslcontext.set_ciphers("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305")
sslcontext.set_ecdh_curve("secp384r1")
#sslcontext.load_verify_locations(MYSERV_CLIENTCRT)
sslcontext.load_cert_chain(MYSERV_FULLCHAIN, MYSERV_PRIVKEY)
class HSTSHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload")
self.send_header("Content-Security-Policy", "default-src 'self'")
self.send_header("X-Content-Type-Options", "nosniff")
self.send_header("X-Frame-Options", "SAMEORIGIN")
self.send_header("X-XSS-Protection", "1; mode=block")
self.send_header("Referrer-Policy", "no-referrer")
SimpleHTTPRequestHandler.end_headers(self)
def main():
try:
os.chdir(MYSERV_WORKDIR)#auto-change working directory
SimpleHTTPRequestHandler.sys_version = "002"#display custom Python system version
SimpleHTTPRequestHandler.server_version = "001"#display custom server software version
my_server = socketserver.ThreadingTCPServer(('', 443), HSTSHandler)
my_server.socket = sslcontext.wrap_socket(my_server.socket, do_handshake_on_connect=False, server_side=True)
print('Starting server, use <Ctrl-C> to stop')
my_server.serve_forever()
except KeyboardInterrupt:
print(' received, shutting down server')
my_server.shutdown()
if __name__ == '__main__':
main()
最佳答案
这是获得相同最终结果的两种不同方式。如果您查看 ThreadingTCPServer
的实现,它只是:
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
在另一个例子中,HTTPServer
只是TCPServer
的一个非常小的包装器(在server_bind
中添加了一个覆盖来存储服务器主机名和自动设置 allow_reuse_address
),然后您的代码直接添加 ThreadingMixIn
。
因此,无论哪种方式,您最终都会经历相同的基本代码。 python 库中的类层次结构随着时间的推移发生了轻微的变化,因此不同的代码示例最终会以不同的组合来执行操作。
就您个人而言,对于您的示例,我发现使用 ThreadingTCPServer
的版本更干净,只是因为一个额外的类在别处处理,因此代码略小。 OTOH,另一个版本允许稍微多一些灵 active ,因为您已经定义了一个点,在该点上您可以控制线程混合的属性,此外,如果这变得重要,您还可以获得额外的 HTTPServer
包装器位给你。
关于python - ThreadingTCPServer 与 ThreadingMixIn HTTPServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58243193/
我正在运行一个简单的 echo 套接字服务器,只要有客户端连接,ctrl C 就不会退出/终止服务器。相反,它会“挂起”,直到客户端与套接字断开连接。我在某处读到这是因为即使在主线程终止后仍有一个线程
我基于示例 here 创建了一个运行 ThreadingTCPServer 的简单测试应用程序 (Python 2.6.1) .如果客户端发送命令“再见”,我想关闭服务器并干净地退出应用程序。退出部分
我想使用 SocketServer 模块为服务器的请求处理程序中的各个连接添加超时。 首先让我说这是我第一次尝试使用 Python 进行网络编程。我已经对 SocketServer.BaseReque
我已经对两个服务器进行了编程,它们基本上使用不同的方法执行相同的操作。两者都是网络服务器,在套接字对象周围有一个非阻塞的 ssl 包装器。线程允许同时处理多个请求。 一个使用 ThreadingTCP
作为 cannot-bind-to-address-after-socket-program-crashes 的后续行动,我的程序重新启动后收到此错误: socket.error: [Errno 98
我是一名优秀的程序员,十分优秀!