>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 25805 个阅读者 刷新本主题
 * 贴子主题:  用Java Socket实现代理服务器程序 回复文章 点赞(0)  收藏  
作者:flybird    发表时间:2019-09-23 17:30:19     消息  查看  搜索  好友  邮件  复制  引用

(1)以下是主服务程序,用来侦听端口
package org.javaren.proxy;

import java.net.ServerSocket;
import java.net.Socket;

public class SocketProxy {
/**
* @param args
*/

public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
new SocketThread(socket).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

(2)核心代码,处理链接的代理线程
内部设计了Socket的认证,自己看吧


package org.javaren.proxy;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class SocketThread extends Thread {
private Socket socketIn;
private InputStream isIn;
private OutputStream osIn;
//
private Socket socketOut;
private InputStream isOut;
private OutputStream osOut;

public SocketThread(Socket socket) {
this.socketIn = socket;
}

private byte[] buffer = new byte[4096];
private static final byte[] VER = { 0x5, 0x0 };
private static final byte[] CONNECT_OK = { 0x5, 0x0, 0x0, 0x1, 0, 0, 0, 0, 0, 0 };

public void run() {
try {
System.out.println("\n\na client connect " + socketIn.getInetAddress() + ":" + socketIn.getPort());
isIn = socketIn.getInputStream();
osIn = socketIn.getOutputStream();
int len = isIn.read(buffer);
System.out.println("< " + bytesToHexString(buffer, 0, len));
osIn.write(VER);
osIn.flush();
System.out.println("> " + bytesToHexString(VER, 0, VER.length));
len = isIn.read(buffer);
System.out.println("< " + bytesToHexString(buffer, 0, len));
// 查找主机和端口
String host = findHost(buffer, 4, 7);
int port = findPort(buffer, 8, 9);
System.out.println("host=" + host + ",port=" + port);
socketOut = new Socket(host, port);
isOut = socketOut.getInputStream();
osOut = socketOut.getOutputStream();
//
for (int i = 4; i <= 9; i++) {
CONNECT_OK[i] = buffer[i];
}
osIn.write(CONNECT_OK);
osIn.flush();
System.out.println("> " + bytesToHexString(CONNECT_OK, 0, CONNECT_OK.length));
SocketThreadOutput out = new SocketThreadOutput(isIn, osOut);
out.start();
SocketThreadInput in = new SocketThreadInput(isOut, osIn);
in.start();
out.join();
in.join();
} catch (Exception e) {
System.out.println("a client leave");
} finally {
try {
if (socketIn != null) {
socketIn.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("socket close");
}

public static String findHost(byte[] bArray, int begin, int end) {
StringBuffer sb = new StringBuffer();
for (int i = begin; i <= end; i++) {
sb.append(Integer.toString(0xFF & bArray[i]));
sb.append(".");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}

public static int findPort(byte[] bArray, int begin, int end) {
int port = 0;
for (int i = begin; i <= end; i++) {
port <<= 16;
port += bArray[i];
}
return port;
}

// 4A 7D EB 69
// 74 125 235 105
public static final String bytesToHexString(byte[] bArray, int begin, int end) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = begin; i < end; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
sb.append(" ");
}
return sb.toString();
}
}

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


package org.javaren.proxy;

/**
* * 从外部读取,向内部发送信息
*/

import java.io.InputStream;
import java.io.OutputStream;

public class SocketThreadInput extends Thread {
private InputStream isOut;
private OutputStream osIn;

public SocketThreadInput(InputStream isOut, OutputStream osIn) {
this.isOut = isOut;
this.osIn = osIn;
}

private byte[] buffer = new byte[409600];

public void run() {
try {
int len;
while ((len = isOut.read(buffer)) != -1) {
if (len > 0) {
System.out.println(new String(buffer, 0, len));
osIn.write(buffer, 0, len);
osIn.flush();
}
}
} catch (Exception e) {
System.out.println("SocketThreadInput leave");
}
}
}

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


[code]package org.javaren.proxy;

import java.io.InputStream;
import java.io.OutputStream;

/**
* 从内部读取,向外部发送信息
*
* @author zxq
*
*/

public class SocketThreadOutput extends Thread {
private InputStream isIn;
private OutputStream osOut;

public SocketThreadOutput(InputStream isIn, OutputStream osOut) {
this.isIn = isIn;
this.osOut = osOut;
}

private byte[] buffer = new byte[409600];

public void run() {
try {
int len;
while ((len = isIn.read(buffer)) != -1) {
if (len > 0) {
System.out.println(new String(buffer, 0, len));
osOut.write(buffer, 0, len);
osOut.flush();
}
}
} catch (Exception e) {
System.out.println("SocketThreadOutput leave");
}
}
}

效果还不错,用firefox/ ie都测试过,可用。


————————————————

原文链接:https://blog.csdn.net/java2000_net/article/details/7826660


程序猿的技术大观园:www.javathinker.net

[这个贴子最后由 admin 在 2020-01-01 12:54:48 重新编辑]
  Java面向对象编程-->对象的生命周期
  JavaWeb开发-->自定义JSP标签(Ⅱ)
  JSP与Hibernate开发-->映射对象标识符
  Java网络编程-->通过JDBC API访问数据库
  精通Spring-->虚拟DOM和render()函数
  Vue3开发-->计算属性和数据监听
  详细介绍float和double类型的区别
  JDK17的新特性
  BIO、NIO和AIO的区别、三种IO的原理与用法
  NIO底层原理
  NIO模式的IO多路复用底层原理
  Java Proxy用法: 让我们创建一个API代理器
  ThreadLocal的内存泄露的原因分析以及如何避免
  使用策略模式优化代码实践,如何让项目快速起飞
  用注解去代替if-else的技巧
  面试必考-static、final和单例模式
  volatile 与 synchronized 详解
  Eclipse使用指南:Debug 配置
  Eclipse使用指南:创建Java项目的步骤
  Java设计模式:享元模式
  Java 入门实用代码:数组扩容
  更多...
 IPIP: 已设置保密
树形列表:   
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。