java tcp实现_使用JAVA实现TCP数据转发

本文介绍如何使用Java编写TCP数据转发程序,通过在中间服务器上运行此程序,实现在本地计算机上直接访问受限数据库或主机。文章提供了一个简单的Java代码示例,并提到该方法适用于Oracle数据库、SSH和Telnet的转发,但不适用于HTTP,因为HTTP协议的Host参数限制。
摘要由CSDN通过智能技术生成

你是否有过这样的使用场景,比如有一个数据库或主机,因为安全、网络的关系,在你的电脑上无法直接访问。但是此时你有一个中间的机子,中间机子可以访问上述的数据库或主机,同时你的电脑可以访问该中间机子。

开动歪脑筋,能否在中间的机子上装一个什么软件,可以在你的电脑上直接访问你之前所不能访问的数据库或主机?

答案是肯定的,在中间机子上装一个TCP数据转发软件就可以了。这种现成的软件很多,linux自带的iptable也可以实现该功能。不过因为原理简单、还是自己动手、丰衣足食吧,上代码:

package com.ai.police.portmap;

import java.net.ServerSocket;

import java.net.Socket;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class TranslatePort {

private transient static Log log = LogFactory.getLog(TranslatePort.class);

public static void main(String[] args) {

try {

if(args == null || args.length<3){

log.error("输出参数不能为空,分别是 本地监听端口、远程IP、远程端口");

return;

}

//获取本地监听端口、远程IP和远程端口

int localPort = Integer.parseInt(args[0].trim());

String remoteIp = args[1].trim();

int remotePort = Integer.parseInt(args[2].trim());

//启动本地监听端口

ServerSocket serverSocket = new ServerSocket(localPort);

log.error("localPort="+localPort + ";remoteIp=" + remoteIp +

";remotePort="+remotePort+";启动本地监听端口" + localPort + "成功!");

while(true){

Socket clientSocket = null;

Socket remoteServerSocket = null;

try {

//获取客户端连接

clientSocket = serverSocket.accept();

log.error("accept one client");

//建立远程连接

remoteServerSocket = new Socket(remoteIp ,remotePort);

log.error("create remoteip and port success");

//启动数据转换接口

(new TransPortData(clientSocket ,remoteServerSocket ,"1")).start();

(new TransPortData(remoteServerSocket ,clientSocket,"2")).start();

} catch (Exception ex) {

log.error("",ex);

}

//建立连接远程

}

} catch (Exception e) {

log.error("",e);

}

}

}

package com.ai.police.portmap;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

/**

* 用于转发数据

* @author Administrator

*

*/

public class TransPortData extends Thread {

private transient static Log log = LogFactory.getLog(TranslatePort.class);

Socket getDataSocket;

Socket putDataSocket;

String type;

public TransPortData(Socket getDataSocket , Socket putDataSocket ,String type){

this.getDataSocket = getDataSocket;

this.putDataSocket = putDataSocket;

this.type = type;

}

public void run(){

try {

while(true){

InputStream in = getDataSocket.getInputStream() ;

OutputStream out = putDataSocket.getOutputStream() ;

//读入数据

byte[] data = new byte[1024];

int readlen = in.read(data);

//如果没有数据,则暂停

if(readlen<=0){

Thread.sleep(300);

continue;

}

out.write(data ,0,readlen);

out.flush();

}

} catch (Exception e) {

log.error("type:"+type,e);

}

finally{

//关闭socket

try {

if(putDataSocket != null){

putDataSocket.close();

}

} catch (Exception exx) {

}

try {

if(getDataSocket != null){

getDataSocket.close();

}

} catch (Exception exx) {

}

}

}

}

测试结果:

1、可以实现对oracle数据库、ssh 、telnet等转发,客户端只要连到中间机子对应的端口上,实现了直接操作后台数据库或主机的功能;

2、上述代码不支持HTTP转发,不能实现的原因并不是因为数据没有转发过去,HTTP是基于TCP上的一种高层协议,tcp数据肯定是转发给对应的web服务器了。不能实现的原因是http协议本身的原因,http请求报文中的host参数包含了目的web服务器的ip和端口,直接转发因为host数据不正确导致真正的web服务器会丢弃该请求;另外,还有其它http协议本身的原因,回头我会专门撰写一篇HTTP数据转发来描述解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值