近期要做一个流媒体播放器,支持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();
           
        }
    }
}