简体   繁体   English

JAVA中的SSL套接字连接池

[英]SSL socket Connection Pooling in JAVA

I am creating a SSL server-client. 我正在创建一个SSL服务器客户端。 Till now, what I have implemented is a simple server which can talk to a single client (no threading, that is). 到目前为止,我实现的是一个可以与单个客户端通信的简单服务器(即没有线程)。 Now, I want to scale this application for multiple clients and I want to use connection pooling for that. 现在,我想为多个客户端扩展此应用程序,并为此使用连接池。 Now, do I need to use threading for that or is there inbuilt library that I can use. 现在,我是否需要为此使用线程,或者是否可以使用内置库。 Any examples, link etc would work. 任何示例,链接等都可以使用。

PS: I have tried googling but have not found a suitable link. PS:我已经尝试使用Google搜索,但没有找到合适的链接。

Below is my code if required: 以下是我的代码(如果需要):

Server: 服务器:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.*;

public class SSLServer {

    public static void main(String args[]){
        String ksname = "file.jks";
        char kspass[] = "pass".toCharArray();
        char ctpass[] = "pass".toCharArray();

        try {
            KeyStore ks = KeyStore.getInstance("JKS");
            ks.load(new FileInputStream(ksname), kspass);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, ctpass);
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(kmf.getKeyManagers(), null, null);
            SSLServerSocketFactory ssf = sc.getServerSocketFactory();
            SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(4321);
            //printServerSocketInfo(s);
            SSLSocket c = (SSLSocket) s.accept();
            //printSocketInfo(c);

            BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream()));
            BufferedWriter w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));

            w.write("Server starts\n");

            w.flush();
            String k = null;
            while((k = r.readLine()) != null){
                //do something
                if(k.equals("end"))
                    break;
                w.write(resolve(k));
                w.newLine();
                w.flush();
            }
            w.close();
            r.close();
            c.close();
            s.close();

        } catch (KeyStoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CertificateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (KeyManagementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }

    private static void printSocketInfo(SSLSocket s) {
          System.out.println("Socket class: "+s.getClass());
          System.out.println("   Remote address = "
             +s.getInetAddress().toString());
          System.out.println("   Remote port = "+s.getPort());
          System.out.println("   Local socket address = "
             +s.getLocalSocketAddress().toString());
          System.out.println("   Local address = "
             +s.getLocalAddress().toString());
          System.out.println("   Local port = "+s.getLocalPort());
          System.out.println("   Need client authentication = "
             +s.getNeedClientAuth());
          SSLSession ss = s.getSession();
          System.out.println("   Cipher suite = "+ss.getCipherSuite());
          System.out.println("   Protocol = "+ss.getProtocol());
    }

    private static void printServerSocketInfo(SSLServerSocket s) {
          System.out.println("Server socket class: "+s.getClass());
          System.out.println("   Socket address = "
             +s.getInetAddress().toString());
          System.out.println("   Socket port = "
             +s.getLocalPort());
          System.out.println("   Need client authentication = "
             +s.getNeedClientAuth());
          System.out.println("   Want client authentication = "
             +s.getWantClientAuth());
          System.out.println("   Use client mode = "
             +s.getUseClientMode());
    }

    private static String resolve(String p){
        //some implementation
        return "something";
    }

    }

Client: 客户:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.UnknownHostException;

import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class SSLClient {

    public static void main(String[] args){

        SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();

        try {
            SSLSocket c = (SSLSocket) f.createSocket("localhost", 4321);
            printSocketInfo(c);
            c.startHandshake();
            BufferedWriter w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));
            BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream()));

            //to input hex code message
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String k = null;
            while((k = r.readLine()) != null){
                //send message to server
                System.out.println(k);
                System.out.flush();
                k = in.readLine();
                if(k.equals("."))
                    break;
                System.out.println(k);
                System.out.flush();
                w.write(k);
                w.newLine();
                w.flush();
            }
            w.close();
            r.close();
            c.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

Your server is able to connect to multiple clients. 您的服务器能够连接到多个客户端。 In your code you've initialized a SSLServerSocket who's task it is to wait for additional clients - each of them will get it's own SSLSocket . 在您的代码中,您初始化了一个SSLServerSocket ,其任务是等待其他客户端-每个客户端都将获得它自己的SSLSocket

If your server isn't able to handle all clients, you'd use something like a loadbalancer which spreads the incoming requests to different server. 如果您的服务器不能处理所有客户端,则可以使用负载平衡器之类的工具 ,它将传入的请求分散到其他服务器。

Connection Pooling is typically used inside a server - eg for talking to a database. 连接池通常用于服务器内部,例如用于与数据库对话。

Does this answer your question? 这回答了你的问题了吗? If not, is your intention to spread the requests to more than one server or to get to know what connection pooling is for? 如果不是,您是打算将请求分发到多个服务器还是要了解连接池的用途?

Connection pooling is implenented at the client. 客户端没有连接池。

At the server end, all you can do is accept connections and not terminate them until closed by the client, or until some read timeout occurs trying to read the second or subsequent request. 在服务器端,您所能做的就是接受连接,直到客户端关闭或在尝试读取第二个或后续请求时发生读取超时时才终止连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM