package org.kne.cloud.network.frpc; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.SocketAddress; import java.net.SocketImpl; import java.net.UnknownHostException; import java.util.Iterator; import java.util.Set; import org.kne.cloud.network.MultiProtocolSocketAddress; public class FrpcServerSocket extends ServerSocket { private FrpcProcess frpc; private FrpcIni frpcini; private String tunnel; public FrpcServerSocket() throws IOException { super(); } public FrpcServerSocket(FrpcIni fi, int port, int backlog, InetAddress bindAddr) throws IOException { super(); this.frpcini=fi; if (port < 0 || port > 0xFFFF) throw new IllegalArgumentException("Port value out of range: " + port); if (backlog < 1) backlog = 50; try { bind(new InetSocketAddress(bindAddr, port), backlog); } catch (IOException | SecurityException e) { close(); throw e; } } public FrpcServerSocket(FrpcIni fi,int port, int backlog) throws IOException { this(fi,port, backlog, null); } public FrpcServerSocket(FrpcIni fi,int port) throws IOException { this(fi,port, 50, null); } public FrpcServerSocket(FrpcIni fi) throws IOException { this(fi,0, 50, null); } protected FrpcServerSocket(SocketImpl impl) { super(impl); } @Override public void bind(SocketAddress endpoint) throws IOException { bind(endpoint, 50); } public String getTunnelHost() { if (!isBound()) return null; return frpcini.getServerAddr(); } public InetAddress getTunnelInetAddress() throws UnknownHostException { if (!isBound()) return null; return InetAddress.getByName( frpcini.getServerAddr()); } public int getTunnelPort() { if (!isBound()) return -1; return frpcini.getRemotePort(tunnel); } public MultiProtocolSocketAddress getTunnelSocketAddress() { if (!isBound()) return null; return new MultiProtocolSocketAddress(frpcini.getType(tunnel).toUpperCase(),getTunnelHost(), getTunnelPort()); } @Override public void bind(SocketAddress endpoint, int backlog) throws IOException { if(frpcini!=null) { if(tunnel==null) { Set e=frpcini.keySet(); for (Iterator iterator = e.iterator(); iterator.hasNext();) { String key = iterator.next(); if(!key.equals("common")) { tunnel=key; break; } } if(tunnel==null) { throw new IllegalArgumentException("cant found avaliable tunnel!"); } } super.bind(endpoint, backlog); InetAddress iad=((InetSocketAddress) endpoint).getAddress(); frpcini.setLocalIP(tunnel,iad.isAnyLocalAddress()?"127.0.0.1": iad.getHostAddress()); frpcini.setLocalPort(tunnel, getLocalPort()); frpcini.setConnectServerLocalIp(((InetSocketAddress)endpoint).getAddress().getHostAddress()); frpc=new FrpcProcess(frpcini.storeToString()); }else { super.bind(endpoint, backlog); } } public FrpcIni getFrpcini() { return frpcini; } public void setFrpcini(FrpcIni frpcini) { this.frpcini = frpcini; } public String getTunnel() { return tunnel; } public void setTunnel(String tunnel) { this.tunnel = tunnel; } @Override public void close() throws IOException { if(frpc!=null) { frpc.destroy(); } super.close(); } /*public MultipurposeSocketAddress getTunnelRemoteSocketAddress() { return new MultipurposeSocketAddress(frpcini.getType(tunnel).toUpperCase(), frpcini.getServerAddr(), frpcini.getRemotePort(tunnel)); }*/ public static void main(String[] args) throws IOException { String str=""" [common] server_addr = us.afrps.cn server_port = 7000 token = afrps.cn protocol=kcp [test5] type = tcp local_ip = 127.0.0.1 local_port = 7461 remote_port = 49966 use_encryption = true use_compression = true """; FrpcIni fi=new FrpcIni(str); FrpcServerSocket fss= new FrpcServerSocket(fi); System.out.println(fss.getTunnelSocketAddress()); System.out.println(fss.accept()); } }