Java实现Socket5代理服务器

时间:2023-03-09 18:09:28
Java实现Socket5代理服务器

直接贴代码,不解释

1 主服务,用来侦听端口

  1. package org.javaren.proxy;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. public class SocketProxy {
  5. /**
  6. * @param args
  7. */
  8. public static void main(String[] args) throws Exception {
  9. ServerSocket serverSocket = new ServerSocket(8888);
  10. while (true) {
  11. Socket socket = null;
  12. try {
  13. socket = serverSocket.accept();
  14. new SocketThread(socket).start();
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. }
  20. }

2 核心代码,处理链接的代理线程

内部设计了Socket的认证,自己看吧

  1. package org.javaren.proxy;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.net.Socket;
  6. public class SocketThread extends Thread {
  7. private Socket socketIn;
  8. private InputStream isIn;
  9. private OutputStream osIn;
  10. //
  11. private Socket socketOut;
  12. private InputStream isOut;
  13. private OutputStream osOut;
  14. public SocketThread(Socket socket) {
  15. this.socketIn = socket;
  16. }
  17. private byte[] buffer = new byte[4096];
  18. private static final byte[] VER = { 0x5, 0x0 };
  19. private static final byte[] CONNECT_OK = { 0x5, 0x0, 0x0, 0x1, 0, 0, 0, 0, 0, 0 };
  20. public void run() {
  21. try {
  22. System.out.println("\n\na client connect " + socketIn.getInetAddress() + ":" + socketIn.getPort());
  23. isIn = socketIn.getInputStream();
  24. osIn = socketIn.getOutputStream();
  25. int len = isIn.read(buffer);
  26. System.out.println("< " + bytesToHexString(buffer, 0, len));
  27. osIn.write(VER);
  28. osIn.flush();
  29. System.out.println("> " + bytesToHexString(VER, 0, VER.length));
  30. len = isIn.read(buffer);
  31. System.out.println("< " + bytesToHexString(buffer, 0, len));
  32. // 查找主机和端口
  33. String host = findHost(buffer, 4, 7);
  34. int port = findPort(buffer, 8, 9);
  35. System.out.println("host=" + host + ",port=" + port);
  36. socketOut = new Socket(host, port);
  37. isOut = socketOut.getInputStream();
  38. osOut = socketOut.getOutputStream();
  39. //
  40. for (int i = 4; i <= 9; i++) {
  41. CONNECT_OK[i] = buffer[i];
  42. }
  43. osIn.write(CONNECT_OK);
  44. osIn.flush();
  45. System.out.println("> " + bytesToHexString(CONNECT_OK, 0, CONNECT_OK.length));
  46. SocketThreadOutput out = new SocketThreadOutput(isIn, osOut);
  47. out.start();
  48. SocketThreadInput in = new SocketThreadInput(isOut, osIn);
  49. in.start();
  50. out.join();
  51. in.join();
  52. } catch (Exception e) {
  53. System.out.println("a client leave");
  54. } finally {
  55. try {
  56. if (socketIn != null) {
  57. socketIn.close();
  58. }
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. System.out.println("socket close");
  64. }
  65. public static String findHost(byte[] bArray, int begin, int end) {
  66. StringBuffer sb = new StringBuffer();
  67. for (int i = begin; i <= end; i++) {
  68. sb.append(Integer.toString(0xFF & bArray[i]));
  69. sb.append(".");
  70. }
  71. sb.deleteCharAt(sb.length() - 1);
  72. return sb.toString();
  73. }
  74. public static int findPort(byte[] bArray, int begin, int end) {
  75. int port = 0;
  76. for (int i = begin; i <= end; i++) {
  77. port <<= 16;
  78. port += bArray[i];
  79. }
  80. return port;
  81. }
  82. // 4A 7D EB 69
  83. // 74 125 235 105
  84. public static final String bytesToHexString(byte[] bArray, int begin, int end) {
  85. StringBuffer sb = new StringBuffer(bArray.length);
  86. String sTemp;
  87. for (int i = begin; i < end; i++) {
  88. sTemp = Integer.toHexString(0xFF & bArray[i]);
  89. if (sTemp.length() < 2)
  90. sb.append(0);
  91. sb.append(sTemp.toUpperCase());
  92. sb.append(" ");
  93. }
  94. return sb.toString();
  95. }
  96. }

3  读取线程,负责外面读数据,写入到请求端

  1. package org.javaren.proxy;
  2. /**
  3. * * 从外部读取,向内部发送信息
  4. */
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. public class SocketThreadInput extends Thread {
  8. private InputStream isOut;
  9. private OutputStream osIn;
  10. public SocketThreadInput(InputStream isOut, OutputStream osIn) {
  11. this.isOut = isOut;
  12. this.osIn = osIn;
  13. }
  14. private byte[] buffer = new byte[409600];
  15. public void run() {
  16. try {
  17. int len;
  18. while ((len = isOut.read(buffer)) != -1) {
  19. if (len > 0) {
  20. System.out.println(new String(buffer, 0, len));
  21. osIn.write(buffer, 0, len);
  22. osIn.flush();
  23. }
  24. }
  25. } catch (Exception e) {
  26. System.out.println("SocketThreadInput leave");
  27. }
  28. }
  29. }

4 写入线程,负责读取请求端数据,写入到目标端

  1. package org.javaren.proxy;
  2. import java.io.InputStream;
  3. import java.io.OutputStream;
  4. /**
  5. * 从内部读取,向外部发送信息
  6. *
  7. * @author zxq
  8. *
  9. */
  10. public class SocketThreadOutput extends Thread {
  11. private InputStream isIn;
  12. private OutputStream osOut;
  13. public SocketThreadOutput(InputStream isIn, OutputStream osOut) {
  14. this.isIn = isIn;
  15. this.osOut = osOut;
  16. }
  17. private byte[] buffer = new byte[409600];
  18. public void run() {
  19. try {
  20. int len;
  21. while ((len = isIn.read(buffer)) != -1) {
  22. if (len > 0) {
  23. System.out.println(new String(buffer, 0, len));
  24. osOut.write(buffer, 0, len);
  25. osOut.flush();
  26. }
  27. }
  28. } catch (Exception e) {
  29. System.out.println("SocketThreadOutput leave");
  30. }
  31. }
  32. }

原文:http://blog.****.net/java2000_net/article/details/7826660