java - 通过代理的新套接字连接
问题描述
我正在两台服务器之间编写代理,一台使用 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。
解决方案
推荐阅读
- sql - SQL 按特定值排序
- typescript - 在 React Native Typescript 中将带参数的函数传递给子组件
- java - 将 Trianglemesh 转换为 FXyz PolygonMesh Javafx
- php - 使用 nginx 服务器 + php 获取特定文件夹的 index.php 404 文件
- asp.net-mvc - .Net Core 文件上传在本地工作但不能在现场工作
- go - 使用反射访问结构中的结构字段
- python - 是否有在 Python 代码中表示数量单位的约定?
- javascript - 未找到 SendMessageComponent 的组件工厂。你把它添加到@NgModule.entryComponents 了吗?
- reactjs - 仅获取日期并仅将日期作为输入提供给 reat-date-picker
- sql - Oracle 查询与版本 < 12 的兼容性问题