Java 为SSL套接字上的每个请求创建新进程会导致“TypeError:无法序列化套接字对象”,但对普通/非SSL套接字执行相同操作也会起作用

Java 为SSL套接字上的每个请求创建新进程会导致“TypeError:无法序列化套接字对象”,但对普通/非SSL套接字执行相同操作也会起作用,java,python,sockets,ssl,Java,Python,Sockets,Ssl,我试图在python服务器和java客户端中使用使用JavaKeyTool生成的密钥和证书。我创建了密钥和密钥库,导出了证书,将证书添加到信任库,将密钥库转换为标准pkcs格式,然后从pkcs中提取密钥和证书以在python服务器中使用。开始的前三个步骤和结束的最后三个步骤。这个问题在某种程度上是后续问题,可以在中找到生成密钥和证书的详细步骤 我的SSL服务器看起来像这样 server.py SSL客户端如下所示: Client4Py.java 我不知道我是否明白确切的原因,但我在这里说明 查看

我试图在python服务器和java客户端中使用使用JavaKeyTool生成的密钥和证书。我创建了密钥和密钥库,导出了证书,将证书添加到信任库,将密钥库转换为标准pkcs格式,然后从pkcs中提取密钥和证书以在python服务器中使用。开始的前三个步骤和结束的最后三个步骤。这个问题在某种程度上是后续问题,可以在中找到生成密钥和证书的详细步骤

我的SSL服务器看起来像这样

server.py

SSL客户端如下所示:

Client4Py.java


我不知道我是否明白确切的原因,但我在这里说明

查看以下stacktrace行:

17        ForkingPickler(file, protocol).dump(obj)
18      File "D:\Programs\python\python-3.6.6-amd64\lib\socket.py", line 185, in __getstate__
19        raise TypeError("Cannot serialize socket object")
20    TypeError: Cannot serialize socket object
似乎多处理模块的方法序列化了传递给它的参数,以便将它们传递给新进程。而且似乎对象无法序列化。但是,似乎可以序列化对象。声明相同,这就是基于套接字的服务器工作的原因。但是,我不明白为什么SSLSocket不可序列化,但套接字对象可以序列化。我的意思是,有任何方法是由套接字对象实现的,而不是由SSLSocket实现的。还请注意,错误发生在,即套接字类中,但不在SSLSocket类中

我想如果有人确认上述原因,即SSLSocket对象不可序列化,套接字对象可序列化,我会确切地解释为什么会出现这种情况,并提供将SSLSocket与多处理模块一起使用的解决方案

变通办法


我最终使用了新的流程。可以找到os.fork的示例。它仅在linux上受支持。因此,我使用了它。

我解决了这个问题,在子进程中用SSLContext将套接字包装在clear中接受套接字。创建SSLContext多处理所需的一切都没有序列化问题

更新:以下是服务器sudo代码,说明了上述解释:

def client_connection_handler(client_socket, client_address, ssl_settings):
    context = ssl.SSLContext()
    context.load_cert_chain(certfile=ssl_settings['certfile'], keyfile=ssl_settings['keyfile'],)
    context.verify_mode = ssl_settings["verify_mode"]
    context.load_verify_locations(cafile=ssl_settings["cafile"])
    client_secured_socket = context.wrap_socket(client_socket, server_side=True)
    #
    # send and receive data
    #
    client_secured_socket.close()


def server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((hostname, port))
    server_socket.listen(5)
    while True:
        # Waiting for client connection
        client_socket, client_address = server_socket.accept()
        concurrent_connections = len(multiprocessing.active_children())
        if max_concurrent_clients > concurrent_connections:
            p = multiprocessing.Process(target=client_connection_handler, args=(client_socket, client_address, ssl_settings))
            p.daemon = True
            p.start()
            continue
        # Max client connection has been reached
        client_socket.close()

请提供答案,而不仅仅是解释
1    Waiting For Connections .........
2    
3    Traceback (most recent call last):
4      File "D:\workspaces\workspace6\PythonServer\server.py", line 40, in <module>
5        start_server_ssl()
6      File "D:\workspaces\workspace6\PythonServer\server.py", line 29, in start_server_ssl
7        process.start()
8      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\process.py", line 105, in start
9        self._popen = self._Popen(self)
10      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\context.py", line 223, in _Popen
11        return _default_context.get_context().Process._Popen(process_obj)
12      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\context.py", line 322, in _Popen
13        return Popen(process_obj)
14      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
15        reduction.dump(process_obj, to_child)
16      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\reduction.py", line 60, in dump
17        ForkingPickler(file, protocol).dump(obj)
18      File "D:\Programs\python\python-3.6.6-amd64\lib\socket.py", line 185, in __getstate__
19        raise TypeError("Cannot serialize socket object")
20    TypeError: Cannot serialize socket object
21    Traceback (most recent call last):
22      File "<string>", line 1, in <module>
23      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\spawn.py", line 99, in spawn_main
24        new_handle = reduction.steal_handle(parent_pid, pipe_handle)
25      File "D:\Programs\python\python-3.6.6-amd64\lib\multiprocessing\reduction.py", line 87, in steal_handle
26        _winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
27    PermissionError: [WinError 5] Access is denied
import socket
import multiprocessing as mup
# import ssl

def worker_ssl(data_socket, client_address):
    print("Inside worker")
    #some processing

def start_server_ssl():

    socketObj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = ("127.0.0.1", 6000)
    socketObj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    socketObj.bind(server_address)
    socketObj.listen(10)

#     ssl_socket = ssl.wrap_socket(socketObj,
#                             server_side = True,
#                             certfile="cert.pem",
#                             keyfile="key.pem")        

    while True:
        print("Waiting For Connections .........\n")
        try:
            data_socket, client_address = socketObj.accept()

            process = mup.Process(target=worker_ssl, args=(data_socket, client_address))            
            process.daemon = True
            process.start()

        except socket.error as msg:
            print (" [ERROR] : %s " % msg)
            continue

    socketObj.close()
#     ssl_socket.shutdown(socket.SHUT_RDWR)
#     ssl_socket.close()

if __name__ == '__main__':
    start_server_ssl()
17        ForkingPickler(file, protocol).dump(obj)
18      File "D:\Programs\python\python-3.6.6-amd64\lib\socket.py", line 185, in __getstate__
19        raise TypeError("Cannot serialize socket object")
20    TypeError: Cannot serialize socket object
def client_connection_handler(client_socket, client_address, ssl_settings):
    context = ssl.SSLContext()
    context.load_cert_chain(certfile=ssl_settings['certfile'], keyfile=ssl_settings['keyfile'],)
    context.verify_mode = ssl_settings["verify_mode"]
    context.load_verify_locations(cafile=ssl_settings["cafile"])
    client_secured_socket = context.wrap_socket(client_socket, server_side=True)
    #
    # send and receive data
    #
    client_secured_socket.close()


def server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((hostname, port))
    server_socket.listen(5)
    while True:
        # Waiting for client connection
        client_socket, client_address = server_socket.accept()
        concurrent_connections = len(multiprocessing.active_children())
        if max_concurrent_clients > concurrent_connections:
            p = multiprocessing.Process(target=client_connection_handler, args=(client_socket, client_address, ssl_settings))
            p.daemon = True
            p.start()
            continue
        # Max client connection has been reached
        client_socket.close()