【发布时间】:2020-05-02 09:07:05
【问题描述】:
我在win10系统上用python写了一个简单的客户端-服务器应用程序。我正在使用 Python 3.7.7。
当客户端连接到服务器时,我收到以下错误:
Sending data
Traceback (most recent call last):
File "Client.py", line 23, in <module>
ssock.send(b'this is a test\n')
File "D:\SecureServer\Python37\lib\ssl.py", line 1003, in send
return self._sslobj.write(data)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
为方便起见,我为客户端和服务器使用相同的证书/密钥。
帮助将不胜感激。 谢谢。
这是代码。
服务器:
import socketserver
import ssl
class RequestServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
allow_reuse_address = True
request_queue_size = 10
daemon_threads = True
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
super().__init__(server_address, RequestHandlerClass, False)
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ctx.verify_mode = ssl.CERT_REQUIRED
client_certs = './certs/ca-chain.cert.pem'
ctx.load_verify_locations(cafile=client_certs)
server_cert = './certs/www.example.com.cert.pem'
server_key = './certs/www.example.com.key.pem'
ctx.load_cert_chain(certfile=server_cert, keyfile=server_key, password=None)
self.socket = ctx.wrap_socket(self.socket, server_side=True)
if (bind_and_activate):
self.server_bind()
self.server_activate()
class RequestHandler(socketserver.StreamRequestHandler):
def handle(self):
print("connection from {}:{}".format(self.client_address[0], self.client_address[1]))
try:
common_name = self._get_certificate_common_name(self.request.getpeercert())
if (common_name is None or common_name != "www.example.com"):
print("rejecting {}".format(common_name))
self.wfile.write('{"accepted": false}\n'.encode())
return
data = self.rfile.readline().strip()
print("data: {}".format(data))
self.wfile.write('{"accepted": true}\n'.encode())
except BrokenPipeError:
print("broken pipe from {}:{}".format(self.client_address[0], self.client_address[1]))
def _get_certificate_common_name(self, cert):
if (cert is None):
return None
for sub in cert.get("subject", ()):
for key, value in sub:
if (key == "commonName"):
return value
server = RequestServer(("127.0.0.1", 3278), RequestHandler)
server.serve_forever()
这是客户端:
import socket
import ssl
if __name__ == '__main__':
ctx = ssl.create_default_context()
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
certs_folder = './certs/'
server_certs = certs_folder + 'ca-chain.cert.pem'
ctx.load_verify_locations(cafile=server_certs)
client_cert = certs_folder + 'www.example.com.cert.pem'
client_key = certs_folder + 'www.example.com.key.pem'
ctx.load_cert_chain(certfile=client_cert, keyfile=client_key, password=None)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
print(sock)
with ctx.wrap_socket(sock, server_side=False, server_hostname="www.example.com") as ssock:
ssock.connect(("127.0.0.1", 3278))
print("SSL established. Peer: {}".format(ssock.getpeercert()))
ssock.send(b'this is a test\n') # this is line 23
【问题讨论】:
标签: python windows ssl socketserver