可以在 JDK1.4 下运行的代码:import java.net.*;
import java.io.*;/*
 *一个简单TCP通道类
 *只进行简单的数据传送,实现两个TCP连接之间无缝通道
 *实际也就是一个简单数据转发服务程序
 */
public class BTcpChannels {
/* 目标机器的IP地址 */
private InetAddress targetAddress = null;
/* 目标机器监听的端口 */
private int targetPort = 0;
/* 程序监听的端口 */
private int port = 5555;
/* 服务器对象 */
ServerSocket serverSocket = null;

ThreadPool pool = ThreadPool.getThreadPool();

/*
 *构造函数
 *在默认的 5555 端口监听
 *@param targetAddress 目标主机地址
 *@param targetPort 目标主机监听端口
 */
public BTcpChannels(InetAddress targetAddress , int targetPort) {
this(targetAddress,targetPort,5555);
}
/*
 *构造函数
 *@param targetAddress 目标主机地址
 *@param targetPort 目标主机监听端口
 *@param port 服务程序监听端口
 */
public BTcpChannels(InetAddress targetAddress , int targetPort , int port) {
this.targetAddress = targetAddress;
this.targetPort = targetPort;
this.port = port;
}
/*
 *启动服务
 */
public void start() {
try {
serverSocket = new ServerSocket(port);
System.out.println ("服务启动成功,已在端口:"+port+" 进行监听!");
Socket s_1 = null;
Socket s_2 = null;
MakeSocket ms = null;
while(true) {
s_1 = serverSocket.accept();
System.out.print (GDateTime4DB.getDateString(System.currentTimeMillis()));
System.out.println ("  有新连接--地址:"+s_1.getInetAddress().getHostAddress()+"  端口:"+s_1.getPort());
ms = new MakeSocket(s_1,targetAddress,targetPort);
pool.getWorkThread().start(ms);
}
} catch(IOException ioe) {
System.out.println ("服务器异常退出");
ioe.printStackTrace();
}
}
/* 测试函数 */
public static void main(String args[]) throws Exception{
//一个模拟 socks 代理服务器的例子
// socks 代理服务器在本机的 1080 端口监听
/*
InetAddress address = InetAddress.getByName("127.0.0.1");
BTcpChannels btc = new BTcpChannels(address,8000);
btc.start();
//*/
//*
if(args.length != 3 ) {
System.out.println ("使用方法:\r\nstart javaw BTcpChannels 监听端口 主机名 端口号");
return;
}

int bport = Integer.parseInt(args[0]);
InetAddress address = InetAddress.getByName(args[1]);
int tport = Integer.parseInt(args[2]);
BTcpChannels btc = new BTcpChannels(address,tport,bport);
btc.start();
//*/
}
}
import java.net.*;
import java.io.*;
/*
 *连接构造类,主要是为了避免服务器错误而导致整个程序卡住
 */
public class MakeSocket implements Runnable {
/* 目标机器的IP地址 */
private InetAddress targetAddress = null;
/* 目标机器监听的端口 */
private int targetPort = 0;
/* 客户端 Socket */
Socket socket_1 = null;
/* 服务器端 Socket */
Socket socket_2 = null;

public MakeSocket(Socket s1 , InetAddress address ,int port) {
socket_1 = s1;
targetAddress = address;
targetPort = port;
}

public void run() {
try {
socket_2 = new Socket(targetAddress,targetPort);
BSocketTunnel bst = new BSocketTunnel(socket_1,socket_2);
} catch(IOException e) {
System.out.println ("连接服务器时出现异常,请检查服务器是否运行正常!");
System.out.println ("新连接--地址:"+socket_1.getInetAddress().getHostAddress()+"  端口:"+socket_1.getPort()+"  同时被断开!");
try {
if(socket_1 != null) socket_1.close();
if(socket_2 != null) socket_2.close();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
}import java.net.*;
import java.io.*;public class BSocketTunnel implements BSocketTunnelListener {

int TIMEOUT = 5*60*1000;

Socket socket_1 = null;
Socket socket_2 = null;

ThreadPool pool = ThreadPool.getThreadPool();
//SocketCloseManager scm = SocketCloseManager.getSocketCloseManager(); public BSocketTunnel(Socket s1, Socket s2) {
socket_1 = s1;
socket_2 = s2;
try {
socket_1.setSoTimeout(TIMEOUT);
socket_2.setSoTimeout(TIMEOUT);
StreamTunnel st1 = new StreamTunnel(socket_1.getInputStream(),socket_2.getOutputStream(),this);
StreamTunnel st2 = new StreamTunnel(socket_2.getInputStream(),socket_1.getOutputStream(),this);
pool.getWorkThread().start(st1);
pool.getWorkThread().start(st2);
} catch (SocketException se) {
se.printStackTrace();
} catch (IOException ioe) {
System.out.println ("socket 取得IO流时出现异常");
ioe.printStackTrace();
}
}
public void close() {
//scm.addSocket(socket_1);
//scm.addSocket(socket_2);
try {
socket_1.close();
socket_2.close();
} catch (IOException ioe) {
System.out.println ("socket 关闭时出现异常");
ioe.printStackTrace();
}
}
}

解决方案 »

  1.   

    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.IOException;public class StreamTunnel implements Runnable {

    InputStream in = null;
    OutputStream out = null;
    BSocketTunnelListener tl = null;
    byte[] buffer = new byte[4096];

    public StreamTunnel(InputStream in , OutputStream out , BSocketTunnelListener tl) {
    this.in = in;
    this.out = out;
    this.tl = tl;
    }

    public void run() {
    int length = 0;
    while(true) {
    try {
    if((length = in.read(buffer))>0) {
    out.write(buffer,0,length);
    } else {
    if(length<0){
    tl.close();
    break;
    }
    }
    } catch(IOException ioe) {
    System.out.println (Thread.currentThread().getName()+" 读写数据时发生错误!");
    break;
    }
    }
    }
    }
    /*
     *一个简单的线程池
     */
    public class ThreadPool {
    //以下是配置信息,可以更改
    static int MAX_THREAD = 1000; //未使用
    static int MIN_THREAD = 12; static private ThreadPool pool = new ThreadPool();
    static public ThreadPool getThreadPool() {
    return pool;
    } private int id = 1; //线程 ID 号,主要用于监视线程的工作情况
    private Stack stack = new Stack(MIN_THREAD);
    private ThreadPool() {
    }

    synchronized public boolean putWorkThread(WorkThread wt) {
    if(stack.size()<MIN_THREAD){
    stack.push(wt);
    System.out.println ("线程池内还有X个线程: "+stack.size());
    return true;
    } else {
    System.out.println ("线程ID为:"+wt.getID()+" 的线程没有放入池中.");
    return false;
    }
    }

    synchronized public WorkThread getWorkThread() {
    WorkThread wt = null;
    if(stack.isEmpty()) {
    wt = new WorkThread(this,id);
    System.out.println ("一个新的线程对象被建立,线程ID:"+id);
    id++;
    } else {
    wt = (WorkThread)stack.pop();
    }
    return wt;
    }
    }/*
     *工作线程类
     */
    public class WorkThread implements Runnable {
    private Object lock = new Object();
    private Runnable runner = null;
    private ThreadPool pool = null;
    private boolean first = true;
    private int id = 0;

    public WorkThread(ThreadPool pool,int id) {
    this.pool = pool;
    first = true;
    this.id = id;
    }

    public int getID() {
    return id;
    }

    public void start(Runnable r) {
    runner = r;
    //如果是第一次执行任务,就开启线程来执行
    if(first) {
    first = false;
    new Thread(this,"线程ID:"+id).start();
    } else {
    //如果是第二次及其以后的任务,就直接唤醒线程
    synchronized(lock) {
    lock.notify();
    }
    }
    }

    public void run() {
    while(true) {
    System.out.println (Thread.currentThread().getName()+" 被调用!");
    if(runner != null) {
    runner.run();
    runner = null; //及时回收资源
    }
    if(pool.putWorkThread(this)) {
    System.out.println (Thread.currentThread().getName()+" 被回收!");
    synchronized(lock) {
    try {
    lock.wait();
    } catch (InterruptedException ie) {
    System.out.println ("停止线程时出现异常");
    }
    }
    } else {
    System.out.println (Thread.currentThread().getName()+" 被丢弃!");
    break;
    }
    }
    }
    }
      

  2.   


    /*
     *一个简单的堆栈类,主要是为了快速的删除元素和取得大小
     */
    public class Stack {

    private Object[] values = null;
    private int pos = 0;

    public Stack() {
    this(10);
    }

    public Stack(int length) {
    values = new Object[length];
    pos = 0;
    }

    public Object push(Object item) {
    if(pos < values.length) {
    values[pos] = item;
    pos++;
    } else {
    Object[] temp = new Object[values.length*2];
    System.arraycopy(values,0,temp,0,values.length);
    values = temp;
    values[pos] = item;
    pos++;
    }
    return item;
    }

    public Object pop() {
    Object temp = null;
    if(pos > 0) {
    temp = values[--pos];
    values[pos] = null;
    }
    return temp;
    }

    public Object peek() {
    Object temp = null;
    if(pos > 0) {
    temp = values[pos-1];
    values[pos] = null;
    }
    return temp;
    }

    public boolean isEmpty() {
    return (pos<1);
    }

    public int size() {
    return pos;
    }
    }
      

  3.   

    不好意思,敲错了
    泰勒i=taile+i=tailei=太累
      

  4.   

    是哪个JDK版本的会出现线程丢失现象?两个都会?
      

  5.   

    代码太长,你自己写的也许有些地方没考虑周全直接用TOMCAT的线程池代码改改不好嘛,绝对可靠。。