首页 > 解决方案 > 通过代理的新套接字连接

问题描述

我正在两台服务器之间编写代理,一台使用 TCP(我们称他为 TCP 服务器),另一台使用 TLS(TLS 服务器)。我在服务器和我的代理之间创建了两个套接字。然后我正在从一个服务器上阅读,在另一个服务器上写作,阅读,写作。这是我的问题:在第二次写作期间,我没有得到 TLS 服务器的答复。

如果我不使用我的代理,我可以在 Wireshark 上看到此时有来自 TLS 服务器的新 SYN/SYN ACK/ACK 交换。所以这是正常的,我无法从中读取,因为他试图与我重新联系。但我也看到从另一端也可以重新连接,这就是为什么我实现线程以能够接受来自 TCP 服务器的新连接,但我不知道如何为两者做这件事。我的想法是使用两个线程,一个用于每个读/写交换,并且可能之前接受连接?

有人有解决方案或想法吗?

代理.java

import javax.net.ssl.SSLSocket;

import java.io.*;
import java.net.*;
import java.lang.*;


public class Proxy {
    
    public static void main(String[] args) throws Exception {
        // Creation of the socket and listening on port 5269
        ServerSocket ss = new ServerSocket(5269);
        //Create socket between I and Serv
        SSLSocket ssls = ClientTrustAll.createTlsSocket(5270);
        
        while (true) {
            Socket s = null;
            
            try {
                System.out.println("Server listening on port 5269");
                s = ss.accept();
                
                
                System.out.println(ssls.getPort());
                System.out.println(ssls.getLocalPort());
                
                // s = new Socket("162.0.126.2", 5269);
                System.out.println("Connection established with the Client");
                
                //For reading from Serv
                DataInputStream inFromServ = new DataInputStream(ssls.getInputStream());
                // For reading from client
                DataInputStream inFromClient = new DataInputStream(s.getInputStream());
                // For writing to client
                PrintWriter outToClient = new PrintWriter(s.getOutputStream(), true);
                // For writing to serv
                PrintWriter outToServ = new PrintWriter(ssls.getOutputStream(), true);
                
                Thread t1 = new ClientToServer(inFromClient, outToServ);
                Thread t2 = new ServerToClient(inFromServ, outToClient);
                t1.start();
                t2.start();
                
            } catch (Exception e) {
                s.close();
                e.printStackTrace();
            }
        }
    }
}

class ClientToServer extends Thread {
    DataInputStream inFromClient = null;
    PrintWriter outToServ = null;
    
    public ClientToServer(DataInputStream inFromClient, PrintWriter outToServ) {
        this.inFromClient = inFromClient;
        this.outToServ = outToServ; 
    }
    
    @Override
    public void run() {
        
        String dataString = "";
        String msgIn = "";
        byte[] messageByte = new byte[1000];
        int bytesRead = 0;
        //Transfer the msg between Client and Serv
        
        try {
            while (msgIn != null) {
                // Read from Client
                bytesRead = inFromClient.read(messageByte);
                msgIn += new String(messageByte, 0, bytesRead);
                System.out.println("Message from the client: " + msgIn + "\n");

                // Write to Server
                outToServ.println(msgIn);
                System.out.println("Message sent in TLS to the serv: " + msgIn + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class ServerToClient extends Thread {
    DataInputStream inFromServ = null;
    PrintWriter outToClient = null;
    
    public ServerToClient(DataInputStream inFromServ, PrintWriter outToClient) {
        this.inFromServ = inFromServ;
        this.outToClient = outToClient;
    }
    
    @Override
    public void run() {
        
        String msgOut = "";
        byte[] messageByte = new byte[1000];
        int bytesRead = 0;
        //Transfer the msg between Client and Serv
        
        try {
            while (msgOut != null) {
                // Read From Server
                bytesRead = inFromServ.read(messageByte);
                msgOut += new String(messageByte, 0, bytesRead);
                System.out.println("Message from the serv: " + msgOut + "\n");
                
                // Write to Client
                outToClient.println(msgOut);
                System.out.println("Message sent in TCP to the client: " + msgOut + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务器.java

import java.io.*;
import java.net.*;

public class Server {
    public static void main(String args[]) throws Exception {
        Server server = new Server();
        server.startServer(5269);
    }
    
    public static Socket startServer(int port) {
        Socket s = null;
        // Creation of the socket and listening on port 5269
        try (ServerSocket ss = new ServerSocket(port)) {
            
            System.out.println("Server listening on port 5269");
            BufferedReader in = null;
            s = ss.accept();
            System.out.println("TCP Connection established with the client");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
}

ClientTrustAll.java

import java.security.*;
import java.io.*;
import java.net.*;
import java.lang.*;

public class ClientTrustAll {
    
    public static void main(String[] args) {
        try {
            ClientTrustAll client = new ClientTrustAll();
            SSLSocket s = client.createTlsSocket(5270);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static TrustManager[] createTrustManager() {
        // Create trust manager which accept all certificates
        X509TrustManager tm = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Accept all certificate for client
                System.out.println("Check client => OK");
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Accept all certificate for server
                System.out.println("Check server => OK");
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
            
        // Create trust manager
        TrustManager[] tms = new TrustManager[1];
        tms[0] = tm;
        return tms;
    }
    
    public static SSLSocket createTlsSocket(int port) {
        TrustManager[] tms = createTrustManager();
        SSLSocket s = null;
        try {
            // Create TCP socket
            Socket sTcp = new Socket("127.0.0.1", port);
            System.out.println("Create TCP Socket with the Server");            
            //For reading
            DataInputStream in = new DataInputStream(sTcp.getInputStream());
            byte[] messageByte = new byte[1000];
            String dataString = "";
            
            //Writing the first message on this socket
            PrintWriter out = new PrintWriter(sTcp.getOutputStream(), true);
            out.println("<stream:stream xmlns:db=\"jabber:server:dialback\" xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:server\" from=\"X\" to=\"Y\" version=\"1.0\">");
            System.out.println("Sent: <stream:stream xmlns:db=\"jabber:server:dialback\" xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:server\" from=\"X\" to=\"Y\" version=\"1.0\">\n");
            
            // Read the answer to send response at the good time
            while (!dataString.contains("stream:features")) {
                int bytesRead = in.read(messageByte);
                dataString += new String(messageByte, 0, bytesRead);
                System.out.println("Message = " + dataString + "\n");
            }
            
            // Writing the second message on the socket
            out.println("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
            System.out.println("Sent: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n");
            
            while (!dataString.contains("<proceed")) {
                int bytesRead = in.read(messageByte);
                dataString += new String(messageByte, 0, bytesRead);
                System.out.println("Message = " + dataString + "\n");
            }
            
            // Create TLS context
            SSLContext context = SSLContext.getInstance("TLSv1.2");
            context.init(null, tms, new SecureRandom());
            
            // Create TLS socket
            SSLSocketFactory sslf = context.getSocketFactory();
            System.out.println("127.0.0.1");
            s = (SSLSocket) sslf.createSocket(sTcp, "127.0.0.1", port, true);
            System.out.println("TLS Connection established with the Server");
            // Start TLS handshake (may be omitted, then it will be done during first read or write) 
            s.startHandshake();
            Thread.sleep(100);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
}

使用 Java 8。

标签: javasslproxy

解决方案


推荐阅读