首页 > 解决方案 > SSL Socket 通信 C-Java 问题。怎么解决?

问题描述

我在 C 和 Java 之间的 SSL 套接字通信方面遇到问题。我附上这两条代码。

客户端.c

int OpenConnection(const char *hostname, int port)
{   int sd;
    struct hostent *host;
    struct sockaddr_in addr;

    if ( (host = gethostbyname(hostname)) == NULL )
    {
        perror(hostname);
        abort();
    }
    sd = socket(PF_INET, SOCK_STREAM, 0);
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = *(long*)(host->h_addr);
    if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
    {
        close(sd);
        perror(hostname);
        abort();
    }
    return sd;
}

SSL_CTX* InitCTX(void)
{   SSL_METHOD *method;
    SSL_CTX *ctx;

    OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
    SSL_load_error_strings();   /* Bring in and register error messages */
    method = TLSv1_2_client_method();  /* Create new client-method instance */
    ctx = SSL_CTX_new(method);   /* Create new context */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}

int main(int count, char *strings[])
{   SSL_CTX *ctx;
    int server;
    SSL *ssl;
    char buf[1024];
    int bytes = 0;
    char *hostname, *portnum;

    if ( count != 3 )
    {
        printf("usage: %s <hostname> <portnum>\n", strings[0]);
        exit(0);
    }
    SSL_library_init();
    hostname=strings[1];
    portnum=strings[2];

    ctx = InitCTX();
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);      /* create new SSL connection state */
    SSL_set_fd(ssl, server);    /* attach the socket descriptor */
    if ( SSL_connect(ssl) == FAIL )   /* perform the connection */
        ERR_print_errors_fp(stderr);
    else
    {   char *msg = "Hello???";

        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
        SSL_write(ssl, msg, strlen(msg));   /* encrypt & send message */
        SSL_free(ssl);
    }
    close(server);         /* close socket */
    SSL_CTX_free(ctx);        /* release context */
    return 0;
}

JavaSSLServer.java

public class JavaSSLServer {
    
    static final int port = 8000;

    public static void main(String[] args) {

    System.setProperty("javax.net.ssl.keyStore","examplestore");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
        
        SSLServerSocketFactory sslServerSocketFactory = 
                (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
        
        try {
            ServerSocket sslServerSocket = 
                    sslServerSocketFactory.createServerSocket(port);
            System.out.println("SSL ServerSocket started");
            System.out.println(sslServerSocket.toString());
            
            Socket socket = sslServerSocket.accept();
            System.out.println("ServerSocket accepted");
            
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            try (BufferedReader bufferedReader = 
                    new BufferedReader(
                            new InputStreamReader(socket.getInputStream()))) {
                String line;
                while((line = bufferedReader.readLine()) != null){
                    System.out.println(line);
                    out.println("Arrived");
                }
            }
            System.out.println("Closed");
            
        } catch (IOException ex) {
            Logger.getLogger(JavaSSLServer.class.getName())
                    .log(Level.SEVERE, null, ex);
        }
    }
    
}

有了这两段代码,一切都可以完美运行。当我想在 SSL_write 之后在 C 代码中插入对 SSL_read 函数的调用时,就会出现问题,如下所示:

SSL_write(ssl, msg, strlen(msg));   /* encrypt & send message */
char response[1024];
do {
     bytes = SSL_read(ssl, response, sizeof(response));
}while(bytes <= 0);
printf("This is the response: %s\n", response);

那时,一切都冻结了,我运行 Java 代码的终端中的输出停止在“ServerSocket Accepted”处。而 C 程序挂在“加密连接”上。如果我在分配变量字节后调用 printf 函数,例如:

printf("Bytes: %d\n", bytes)

它永远打印“字节:-1”。当我用 CTRL+C 完成 C 程序时,我从 C 发送的消息出现在 Java 终端中。有人可以帮我解决这个问题吗?

标签: javacsocketsssl

解决方案


推荐阅读