【问题标题】:SSL socket Connection Pooling in JAVAJAVA中的SSL套接字连接池
【发布时间】:2015-11-12 14:09:06
【问题描述】:

我正在创建一个 SSL 服务器客户端。到目前为止,我实现的是一个简单的服务器,它可以与单个客户端通信(即没有线程)。现在,我想为多个客户端扩展这个应用程序,并且我想为此使用连接池。现在,我需要为此使用线程还是有可以使用的内置库。任何示例、链接等都可以。

PS:我试过谷歌搜索,但没有找到合适的链接。

如果需要,下面是我的代码:

服务器:

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";
    }

    }

客户:

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

【问题讨论】:

  • 这里没有任何类型的连接池。您发布的代码创建一个连接,然后退出。它不需要连接池。完全不清楚你在这里问什么,或者你是否知道真正的连接池是什么,或者你为什么认为你需要它。

标签: java multithreading sockets ssl connection-pooling


【解决方案1】:

您的服务器能够连接到多个客户端。在您的代码中,您已经初始化了一个 SSLServerSocket,其任务是等待其他客户 - 他们每个人都将获得自己的 SSLSocket

如果您的服务器无法处理所有客户端,您可以使用 loadbalancer 之类的东西,将传入的请求分散到不同的服务器。

连接池通常在服务器内部使用 - 例如用于与数据库通信。

这是否回答了您的问题?如果不是,您是否打算将请求分散到多个服务器或了解连接池的用途?

【讨论】:

  • 好的。我的最终目标是实现一个可以服务大量请求的应用程序。我才刚刚开始,所以如果你能回答一些疑问。
  • 如果您要为您的应用程序使用像 tomcat 这样的应用程序服务器,那么服务器将执行 thread-stuff。如果您想实现自己的小型服务器,那么我确实会为每个套接字创建一个线程——这意味着为每个客户端。当然,这取决于您对服务器所做的事情,但使用实际的标准硬件,您可以为 >>** 很多**
  • 谢谢。它有帮助。那么,你的意思是我不需要自己实现线程吗?
  • 视情况而定!您想使用/构建 javaee 服务器或应用程序服务器,还是想自己构建自己的套接字处理服务器?如果最后一件事,那么您必须使用 Threads!
  • 好的。我想最后一件事。这是情况-客户端请求的内部处理需要与另一台服务器进行一些处理,我需要与之建立安全连接(这台服务器不是数据库)。现在,我可以在这种情况下使用连接池吗?如果是,如何实现(链接/参考),如果不是,可以使用什么(类似)?
【解决方案2】:

连接池在客户端实现。

在服务器端,您所能做的就是接受连接,直到被客户端关闭,或者在尝试读取第二个或后续请求时发生读取超时。

【讨论】:

  • 我已经阅读和理解的内容,连接池,简单来说就是提前保留一些已经创建的(可能是持久的)连接,并将其提供给请求它的客户端。那么,为什么要在客户端(而不是服务器)上实现它
  • 即使它是正确的,你能否请我参考一些文档/链接等,以便我可以理解并为我的应用程序实现它
  • 你的问题没有意义。服务器无法与客户端建立连接。只有客户端可以通过自己的连接池执行此操作。我已经为您提供了足够的服务器端实现信息。
  • 好的。我明白了,即。为什么在客户端上实现池。您能否也参考一下如何改进我当前的连接池实现。
  • 为什么?您发布的代码创建一个连接,然后退出。它不需要连接池。完全不清楚你在这里问什么,或者你是否知道真正的连接池是什么,或者你为什么认为你需要它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 2015-11-29
  • 2013-09-18
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多