Criar um novo processo para cada solicitação no soquete SSL fornece "TypeError: Não é possível serializar o objeto de soquete", mas fazer o mesmo com os soquetes normais / não SSL

Estou tentando usar chaves e certificados gerados usando javakeytool no servidor python e no cliente java. Criei key & keystore, certificado exportado, adicionei o certificado ao armazenamento confiável, converti o keystore para o formato pkcs padrão e extraí a chave e o certificado do pkcs para usar no servidor python. (três primeiros passos deaqui e últimos três passos deaqui) Esta questão é um pouco de acompanhamento deessa questão etapas detalhadas para gerar chave e certificado podem ser encontradas emaquela questão.

Meu servidor SSL fica assim

server.py

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 = ssl_socket.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()

O cliente SSL fica assim:

Client4Py.java

import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

public class Client4Py {
    static KeyStore ks;
    static KeyManagerFactory kmf;
    static TrustManagerFactory tmf;
    static SSLContext sc;
    static TrustManager[] trustManagers;

    static {
        try {
            ks = KeyStore.getInstance("JKS");
            ks.load(new FileInputStream("D:\\javasslstores\\truststore.jks"), "passwd123".toCharArray());

            kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "passwd123".toCharArray());

            tmf = TrustManagerFactory.getInstance("SunX509"); 
            tmf.init(ks);

            sc = SSLContext.getInstance("TLS"); 

            sc.init(null, tmf.getTrustManagers(), null);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace());
        }
    }

    public static void main(String[] args) throws IOException {
        SSLSocketFactory ssf = sc.getSocketFactory();
        SSLSocket socket = (SSLSocket) ssf.createSocket("127.0.0.1", 6000);
        socket.startHandshake();

        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),StandardCharsets.UTF_8)));
        //PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

        out.println("<<startMessage>>");
        out.println("Message from Client4Py");
        out.println("<<endMessage>>");
        out.flush();

        if (out.checkError())
            System.out.println(
                "SSLSocketClient:  java.io.PrintWriter error");

        out.close();
        socket.close();
    }
}

A saída no console do servidor após a primeira execução do servidor e, em seguida, o cliente é a seguinte:

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

Você pode ver na linha 20, háTypeError: Cannot serialize socket object.

O código começa a funcionar após a remoção de todos os itens SSL

Quando eu comento ligar parawrap_socket()substituirssl_socket.accept() comsocketObject.accept() e comentessl_socket.shutdown() eclose(), o código começa a funcionar. Ele cria um novo processo a partir deworker() conforme desejado e termina a impressãoInside worker no console. Aqui está o servidor não SSL modificado:

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()

questionAnswers(1)

yourAnswerToTheQuestion