java socket处理--修改输入、输出流

近期要做一个流媒体播放器,支持rtsp播放过程中,要记录客户端请求的信息(解析rtsp 请求信息,获取想要的参数)。这时用到了对socket  输入、输出流拦截、处理的操作。

为了提高系统性能,引入的多线程操作,详见代码.

一、程序入口,启动多线程:

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(8042);
        while (true) {
            Socket socket = null;
           
            try {
                socket = serverSocket.accept();
                SocketThread st = new SocketThread(socket);
                st.start();
            } catch (Exception e) {
                System.out.print("socket代理报错!!");
                e.printStackTrace();
            }
        }
    }
}

二、多线程处理

启动处理输入流、输出流的线程。

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;
    }
    public void run() {
        try {
            isIn = socketIn.getInputStream();
            osIn = socketIn.getOutputStream();
            // 流媒体主机IP
            String host = "10.4.121.195";
            // 流媒体主机端口
            int port = 554;
            socketOut = new Socket(host, port);
            isOut = socketOut.getInputStream();
            osOut = socketOut.getOutputStream();
            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.print("线程类报错");
            e.printStackTrace();
        } finally {
            try {
                if (socketIn != null) {
                    socketIn.close();
                }
                if (socketOut != null) {
                    socketOut.close();
                }
            } catch (IOException e) {
                System.out.print("线程关闭报错");
                e.printStackTrace();
            }
        }
    }
}

三、输入流处理

/**
 * * 从外部读取,向内部发送信息
 */
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;
    }
    byte[] buffer = new byte[4096];
    public void run() {
        try {
            int len;
            while ((len = isOut.read(buffer)) != -1) {
                if (len > 0) {
                    String tempStr = new String(buffer, 0, len,"ISO_8859_1");
                    //System.out.println("输出:"+tempStr);
                    //Thread.sleep(100);
                    osIn.write(buffer,0,len);
                    osIn.flush();
                }
            }
        } catch (Exception e) {
           if(e.getMessage().indexOf("Software")==-1)
           {
               System.out.print("输出流报错!!");
               e.printStackTrace();
           }
        }
    }
}

四、输出流处理:

import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.sql.Timestamp;

/**
 * 从内部读取,向外部发送信息
 * @author zxq
 */
public class SocketThreadOutput extends Thread {
    private InputStream isIn;
    private OutputStream osOut;
    private String tspCode = null;

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

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

public void run() {
        try {
            int len ;
            while ((len = isIn.read(buffer)) != -1) {
                if (len > 0) {
                    String tempStr = new String(buffer, 0, len,"GBK");
      //System.out.println("输入:"+tempStr);
                    String regex = "\\?tspCode=([^\\s&]+)(\\s|&)";   
                    Pattern pattern = Pattern.compile(regex);
                    Matcher matcher = pattern.matcher(tempStr);
                    DateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                    if(matcher.find()) {
                        tspCode = matcher.group(1);
                        System.out.println("获取到tspCode="+tspCode+",根据tspCode进行鉴权");
                        tempStr = tempStr.replaceAll("\\"+matcher.group(0)," ");
                        System.out.println("记录访问时间:"+sdf.format(new Timestamp(System.currentTimeMillis())));
                    }
                   tempStr = tempStr.replaceAll("rtsp://10.4.127.160", "rtsp://10.4.121.195");
       tempStr = tempStr.replaceAll("rtsp://218.24.170.156", "rtsp://10.4.121.195");
                   tempStr = tempStr.replaceAll("8042", "554");
                   System.out.println("输入:"+tempStr);
                    osOut.write(buffer, 0, len);
                    osOut.flush();
                }
            }
        } catch (Exception e) {
            //System.out.print("输入流报错!!");
            //e.printStackTrace();
           
        }
    }
}

时间: 2024-12-07 03:47:01

java socket处理--修改输入、输出流的相关文章

java I/O系统(输入输出流)

java I/O系统(输入输出流) 流的特性1.含有流质(数据)2.它有方向(读或写) 流的分类: 输入流和输出流 输入流:io包中的输入流继承自抽象类InputStream或Reader 输出流:io包中的输入流继承自抽象类OutputStream或Writer 字节流和字符流 注:1字节代表1个英文单词存储的数据大小,一个汉字占两字节 1.字节流:以byte为最小单位传送,继承自抽象类InputStream或OutputStream,用于处理二进制文件,InputStream为读取字节流的父

java中常见的输入输出流案例学习

字节输入流: 1.FileInputStream 用途:从文件系统中的文件获得输入字节,常用于读取图像.声音等原始字节流,读取字符流可考虑使用FileReader 详细构造函数与常用方法可参考API文档,网上已经有中文版的API了,我是个E文盲,伤不起 这里介绍一个最常见的方法: read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中. ->off:b字节数组中的偏移量 小知识:数组偏移量,比如a[1,2,3,4,5]

【Java】利用文件输入输出流完成把一个文件夹内的所有文件拷贝的另一的文件夹的操作

一.基本目标 使用Java完成如下的操作: 把一个文件夹内的所有文件拷贝的另一的文件夹,例如,在F盘中有a与b两个文件夹: f:/a里面有一堆文件,运行Java程序之后就会全部复制到f:/b,并且完成重命名,在所有文件之前加rename_的前缀,如果里面有文件夹,则文件夹不重命名,里面的文件进行重命名,同样在所有文件之前加rename_的前缀: 二.制作过程 1.首先主函数非常简单,就是调用了上面FileTest类中的copyFolder函数 public class FileCopy { pu

java之九 基本输入输出流

流的概念 Java程序通过流来完成输入/输出.流是生产或消费信息的抽象.流通过Java的输入/输出系统与物理设备链接.尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式.这样,相同的输入/输出类和方法适用于所有类型的外部设备.这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字.同样,一个输出流可以输出到控制台,磁盘文件或相连的网络.流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同. Java中流的实现是在java.io包定义的类层次结

Java输入输出流

1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读写数据的标准方法.任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法. Java.io是大多数面向数据流的输入/输出类的主要软件包.此外,Java也对块传输提供支持,在核心库 java.nio中采用的便是块IO. 流IO的好处是简单易用,缺点是效率较低.块IO效率很高,但编程比较

【转载】Java输入输出流-IO

转自:http://blog.csdn.net/hguisu/article/details/7418161 1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读写数据的标准方法.任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法. Java.io是大多数面向数据流的输入/输出类的主要软件包.此外,Java也对块传输提供支持,在核

java输入输出流总结 转载

一.基本概念 1.1 什么是IO?     IO(Input/Output)是计算机输入/输出的接口.Java中I/O操作主要是指使用Java进行输入,输出操作.     Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.      任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法.Java.io是大多数面向数据流的输入/输出类的主要软件包.此外,Java也对块传输提供支持,在核心库 java.nio中采用的便是块IO.    

Java中IO流,输入输出流概述与总结

总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都是抽象类InputStream(字节输入流),或者抽象类Reader(字符输入流)的子类: 而所有输出流都是抽象类OutputStream(字节输出流)或者Writer(字符输出流)的子类. [首先需要明白的是:流是干什么的???(为了永久性的保存数据)   根据数据流向的不同分为输入流和输出流:   根据处理数据类型的不同分为字符流和字

Java输入输出流的使用详细介绍

出处:http://www.jb51.net/article/36138.htm 1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读写数据的标准方法.任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法. Java.io是大多数面向数据流的输入/输出类的主要软件包.此外,Java也对块传输提供支持,在核心库 java.nio中采用