目前只是个简单版本,有一些难点没有突破(vi编辑器的处理)

package telnet.server;import jinghai.base.Environment;
import telnet.TelnetProxyMain;
import telnet.handle.Handle;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.LinkedList;
import java.util.concurrent.CountDownLatch;/*** @author Chun* @create 2021-04-02 10:46**/
public class TelnetProxyServer extends Thread {Socket client;Socket accept;InputStream inServer;OutputStream outClient;CountDownLatch countDownLatch;public volatile static STATUS status;//状态public static STATUS login; //登录三个过程private static int index = 0;private static final int temp13 = 13;public TelnetProxyServer(Socket client, Socket accept, InputStream inServer, OutputStream outClient, CountDownLatch countDownLatch) throws IOException {this.client = client;this.accept = accept;this.inServer = inServer;this.outClient = outClient;this.countDownLatch = countDownLatch;}@Overridepublic void run() {LinkedList<Integer> linkedListProxyClient = new LinkedList<>();status = STATUS.CONNECT;    //设置状态login = STATUS.CONNECT;  //登录过程验证使用while (!accept.isClosed() && !client.isClosed()) {try {if (TelnetProxyMain.readClient == -1 || TelnetProxyMain.readServer == -1) break;TelnetProxyMain.readServer = inServer.read();} catch (IOException e) {e.printStackTrace();}//三个状态,连接,登录,交互(登录成功)if (status.getStatus().equalsIgnoreCase("CONNECT")) {   //连接过程直接将获取的值传给TelnetServer即可connectStatus(outClient);} else {//处理LOGIN和INTERACTIVE,存在公用部分try {statusPublic(inServer, outClient, linkedListProxyClient);} catch (IOException e) {e.printStackTrace();}}}countDownLatch.countDown();}private void connectStatus(OutputStream outClient) {try {outClient.write(TelnetProxyMain.readServer);//前21字节是连接过程产生的,第21个字节ascii是3表示正文结束(3 => 0x03 => ETX => (end of text) =>  正文结束)if (TelnetProxyMain.readServer == 3) {//TODO status状态转为Loginstatus = status.nextState(); //状态后移}} catch (IOException e) {e.printStackTrace();}}//老版,根据interactiveStatus去改private void checkLogin(boolean b, InputStream inServer, OutputStream outClient, LinkedList<Integer> linkedListProxyClient, byte[] bytes) throws IOException {if (b) {outClient.write(TelnetProxyMain.readServer);outClient.write(inServer.read());login = login.nextState();System.out.println("LegalOrder: " + new String(bytes));} else {inServer.read();    //去掉换行10outClient.write(27);outClient.write(27);}linkedListProxyClient.clear();index = 0;}private void statusPublic(InputStream inServer, OutputStream outClient, LinkedList<Integer> linkedListProxyClient) throws IOException {if (TelnetProxyMain.readServer == 10) {// 13表示回车键,10表示换行符(windows下是/r/n,linux下/n) ,证明输入结束,对输入的命令进行校验,合法发送给服务器,不合法打回//区分LOGIN和INTERACTIVE,如果用户名密码不需要拦截,则不用区分
//                if (status.getStatus().equalsIgnoreCase("LOGIN")) {//                    loginStatus(inServer, outClient, linkedListProxyClient);
//                } else if (status.getStatus().equalsIgnoreCase("INTERACTIVE")) {// TODO 这里处理命令交互过程interactiveStatus(inServer, outClient, linkedListProxyClient);
//                }} else if (TelnetProxyMain.readServer == 8) { // 删除backspaceif (index != 0 && linkedListProxyClient.size() != 0) {linkedListProxyClient.remove(--index);}outClient.write(TelnetProxyMain.readServer);} else if (TelnetProxyMain.readServer == 27) {specialButtons(inServer, outClient, linkedListProxyClient);//特殊按键的处理,上下左右,home,end等} else if (TelnetProxyMain.readServer == 127) { //delete按键暂时没处理} else if (TelnetProxyMain.readServer != 3 && TelnetProxyMain.readServer != 13) {linkedListProxyClient.add(index++, TelnetProxyMain.readServer);outClient.write(TelnetProxyMain.readServer);}}private void specialButtons(InputStream inServer, OutputStream outClient, LinkedList<Integer> linkedListProxyClient) throws IOException {ByteArrayOutputStream special = new ByteArrayOutputStream();    //处理特殊字符上下左右,home、end、esc等special.write(TelnetProxyMain.readServer);int read = inServer.read();if (read == 91) {special.write(91);int read1 = inServer.read();//读一位if (read1 == 68 || read1 == 67) {//左右special.write(read1);outClient.write(special.toByteArray());if (read1 == 68 && index > 0) {index--;}if (read1 == 67 && index < linkedListProxyClient.size()) {index++;}}//其他目前来说直接过滤了else if (read1 == 65 || read1 == 66) {special.write(read1);outClient.write(special.toByteArray());} else if (read1 == 49 || read1 == 52) {special.write(inServer.read());outClient.write(special.toByteArray());}} else if (read == 27) { //escoutClient.write(TelnetProxyMain.readServer);//清空outClient.write(read);linkedListProxyClient.clear();index = 0;}}//三个过程:用户名,密码,域名private void loginStatus(InputStream inServer, OutputStream outClient, LinkedList<Integer> linkedListProxyClient) throws IOException {//转换成byte数组byte[] bytes = listToBytes(linkedListProxyClient);// TODO 这之后对用户名密码做拦截if (login.getStatus().equalsIgnoreCase("CONNECT")) {  // 用户名boolean b = Handle.checkUserName(bytes);checkLogin(b, inServer, outClient, linkedListProxyClient, bytes);} else if (login.getStatus().equalsIgnoreCase("LOGIN")) {  //密码boolean b = Handle.checkPassWord(bytes);checkLogin(b, inServer, outClient, linkedListProxyClient, bytes);} else if (login.getStatus().equalsIgnoreCase("INTERACTIVE")) {  //域名boolean b = Handle.checkDomainName(bytes);checkLogin(b, inServer, outClient, linkedListProxyClient, bytes);//TODO status状态转为INTERACTIVEif (b) status = status.nextState();index = 0;}}private void interactiveStatus(InputStream inServer, OutputStream outClient, LinkedList<Integer> linkedListProxyClient) throws IOException {//转换成byte数组byte[] bytes = listToBytes(linkedListProxyClient);String command = new String(bytes).trim();// TODO 对键入的命令检查校验boolean b = Handle.checkCommand(command);if (b) {if (Environment.isWindows) outClient.write(temp13);outClient.write(TelnetProxyMain.readServer);System.out.println("LegalOrder: " + new String(bytes));} else {for (int i = 0; i < bytes.length; i++) {outClient.write(8);}System.out.println(bytes.length + "个8");}linkedListProxyClient.clear();index = 0;}private byte[] listToBytes(LinkedList<Integer> linkedListProxyClient) {Integer[] ints = linkedListProxyClient.toArray(new Integer[0]);int len = ints.length;byte[] bytes = new byte[len];for (int i = 0; i < len; i++) {bytes[i] = (byte) (int) ints[i];}return bytes;}}
package telnet.client;import telnet.TelnetProxyMain;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;/*** @author Chun* @create 2021-04-02 10:46**/
public class TelnetProxyClient extends Thread {Socket client;Socket accept;InputStream inClient;OutputStream outServer;CountDownLatch countDownLatch;public TelnetProxyClient(Socket client, Socket accept, InputStream inClient, OutputStream outServer, CountDownLatch countDownLatch) {this.client = client;this.accept = accept;this.inClient = inClient;this.outServer = outServer;this.countDownLatch = countDownLatch;}@Overridepublic void run() {while (!accept.isClosed() && !client.isClosed()) {try {if (TelnetProxyMain.readServer == -1 || TelnetProxyMain.readClient == -1) break;TelnetProxyMain.readClient = inClient.read();
//                System.out.println("返回="+TelnetProxyMain.readClient);outServer.write(TelnetProxyMain.readClient);} catch (IOException e) {try {outServer.flush();e.printStackTrace();} catch (IOException ioException) {ioException.printStackTrace();}break;}}countDownLatch.countDown();}
}
package telnet;import telnet.client.TelnetProxyClient;
import telnet.server.TelnetProxyServer;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;/*** @author Chun* @create 2021-04-08 8:59**/
public class TelnetProxyMain {private final ServerSocket serverSocket;private final Socket client;private final Socket accept;private final InputStream inServer;private final OutputStream outServer;private final InputStream inClient;private final OutputStream outClient;public volatile static int readServer = 0;public volatile static int readClient = 0;private final CountDownLatch countDownLatch = new CountDownLatch(2);public TelnetProxyMain(String ip, int serverPort) throws IOException {serverSocket = new ServerSocket(55);accept = serverSocket.accept();inServer = accept.getInputStream();outServer = accept.getOutputStream();client = new Socket(ip, serverPort);inClient = client.getInputStream();outClient = client.getOutputStream();}/**** 思路1:(采用)目前实现思路是server接收客户端的字节,接收到保留并发送给telnetServer,当输入回车时去校验命令是否合法*    **出现的问题:当我们键入↑↓时应该是返回上一次的命令,这里有个问题就是当我们输入回车后client发送的只有回车并没有将命令发送过来,*      这样就导致我们接收到了空,无法对此命令进行拦截** 思路2:在TelnetServer发送给client处也就是我们自己实现的client处进行拦截发送的字节,*      拦截到就拼接,拼接成字符串,在server处仍然监听回车,敲入回车后校验命令是否合法。*    **出现的问题:这样会拦截到我们输入↑↓后server发送给client的命令,但是当我们在vi/vim编辑器里使用↑↓同样会出现问题。** ** 注:client我们输入命令后客户端想要显示,是需要server将这个字母的字节发送给client的,*      也就是client发送给server一个a(97),server就需要回复client一个a(97)*/public void run() {try {//启动两个线程,分别作为代理的client和servernew TelnetProxyServer(client, accept, inServer, outClient, countDownLatch).start();new TelnetProxyClient(client, accept, inClient, outServer, countDownLatch).start();countDownLatch.await(); //等待两个子线程结束在执行} catch (InterruptedException | IOException e) {e.printStackTrace();} finally {try {client.close();accept.close();serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) {try {TelnetProxyMain telnetProxyMain = new TelnetProxyMain(args[0],50000);telnetProxyMain.run();} catch (IOException e) {e.printStackTrace();}}
}

JAVA实现telnet代理,对输入命令拦截相关推荐

  1. telnet或SQLplus下命令输入错误如何删掉重新输入

    转载自:http://blog.itpub.net/29734436/viewspace-1338985/ 在telnet或SQLplus下命令输入错误,比如下面的情况,如何删掉重新输入? telne ...

  2. 【Java】Java编写Telnet客户端,连接到Windows的Telnet服务器,执行命令和批处理脚本

    Java编写Telnet客户端,连接到Windows的Telnet服务器,执行命令和批处理脚本,同时解决了中文乱码的问题. 源代码和Jar包在这里下载:http://download.csdn.net ...

  3. java中动态代理实现机制

    v前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关 ...

  4. java 反射 动态代理

    在上一篇文章中介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大 ...

  5. 把java文件打包成.jar (jar命令详解)

    把java文件打包成.jar (jar命令详解) 先打开命令提示符(win2000或在运行框里执行cmd命令,win98为DOS提示符),输入jar Chelp,然后回车(如果你盘上已经有了jdk1. ...

  6. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的连接恢复和命令拦截...

    这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第四篇:MVC程序中实体框架的连接恢复和 ...

  7. Java设计模式之行为型:命令模式

    前言: 在开发中,我们可能需要向某些对象发送一些请求,但我们不知道请求的具体接收者是谁,也不知道被请求的操作是哪个,只知道在系统运行中指定具体的请求接收者即可,打个比方,电视遥控器,我们只需知道按哪个 ...

  8. 如何使用 Java 中执行 Windows 的 CMD 命令

    如何使用 Java 中执行 Windows 的 CMD 命令 核心代码 完整代码   在 CMD 中执行 BAT 脚本对用户不友好,而且有安全隐患,因此笔者编写了一些可以在 Java 中执行 Wind ...

  9. telnet/ftp/netstat/ping命令詳細介紹

     很多朋友问到telnet/ftp/netstat/ping 命令的使用方法 今天我就抽点时间做个telnet/ftp/netstat/ping 命令一詳細介紹! 请入门者静下心来.......... ...

最新文章

  1. day26 re正则表达式
  2. 安卓x86程序安装目录_电脑上的安卓系统体验
  3. Redis进阶-Jedis以及Spring Boot操作 Redis 5.x Cluster
  4. producer send源码_Kafka源码深度剖析系列(七)——Producer核心流程初探
  5. SAE帮助「海底小纵队学英语」全面拥抱Serverless
  6. 腾讯安全科恩实验室发布最新研究成果,针对奔驰车载娱乐系统的安全研究
  7. 8086架构/流水线及其优化
  8. 【基础】算法时空复杂度【OI缩水版】
  9. Apriori算法+python实现
  10. 管理感悟:主管要怎样开会才正确
  11. windows 安装msi 出现报错 2503 无权限 使用cmd模式安装
  12. vue单元测试vue test utils使用初探
  13. 台式计算机有哪些部分组成,常用台式电脑的基本组成
  14. python selenium清除缓存,Selenium Python:无法清除chrome浏览器缓存
  15. 轻松搞定应用启动黑白屏
  16. 用C语言求解一元二次方程组
  17. 计算机中的同步和异步
  18. 多个图元合并其中相邻的图元
  19. WK2204 - spi转uart调试记录
  20. 免费OA系统平台在企业发展中的优势(转载)

热门文章

  1. 刷题向》一道逆向思维题(BZOJ1046)(NORMAL)
  2. JavaWeb学习过程 之c3p0的使用
  3. .Net学习笔记----2015-06-30(超市收银系统01-仓库类)
  4. DB2 常用命令小结
  5. 10 个十分难得的 javascript 开发经验
  6. [Leedcode][JAVA][第445题][链表][栈]
  7. ios php rsa,RSA 加密 iOS
  8. java两种绑定方式_Javascript绑定事件的两种方式的区别
  9. 鳗鱼刺多怎么处理图像_怎么在做鱼前去除鳗鱼刺?
  10. linux虚拟服务器新增磁盘怎么挂载,如何在vmware虚拟机Linux中增加硬盘的方法(教程)...