免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3960 | 回复: 17
打印 上一主题 下一主题

[Android] 代理服务器只能给客户端发送第一组消息 [复制链接]

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-06-21 22:58 |只看该作者 |倒序浏览
最近作一个代理服务器程序,使用来转发视频的,可是他只能给我把第一条请求转发过来,剩下的数据就发布回来了,然后视频就无法播放了
  1. package com.liujiaqi.proxy;

  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileReader;
  6. import java.io.IOException;
  7. import java.io.PrintWriter;

  8. public class proxy {
  9.         private static File file = new File("proxy.ini");       //配置文件
  10.         private static String host = "http://localhost/";  //Web服务器地址
  11.         private static int port = 9090;

  12.         public static void createFile() {                          //使用默认参数创建配置文件的函数
  13.                 try {
  14.                         file.createNewFile();
  15.                         PrintWriter writer = new PrintWriter(file);
  16.                         writer.println("<host>" + host);
  17.                         writer.println("<port>" + port);
  18.                         writer.flush();
  19.                         writer.close();
  20.                 } catch (IOException e) {
  21.                         e.printStackTrace();
  22.                 }
  23.         }

  24.         public static void readFile() {                            //读取配置文件中的参数
  25.                 try {
  26.                         String temp = null;
  27.                         BufferedReader reader = new BufferedReader(new FileReader(file));
  28.                         while ((temp = reader.readLine()) != null) {
  29.                                 switch (temp.substring(temp.indexOf("<") + 1,
  30.                                                 temp.lastIndexOf(">"))) {
  31.                                 case "host":
  32.                                         host = temp.substring(temp.lastIndexOf(">") + 1);
  33.                                         break;
  34.                                 case "port":
  35.                                         port = Integer.parseInt(temp.substring(temp
  36.                                                         .lastIndexOf(">") + 1));
  37.                                         break;
  38.                                 default:
  39.                                         break;
  40.                                 }
  41.                         }
  42.                         reader.close();
  43.                 } catch (FileNotFoundException e) {
  44.                         e.printStackTrace();
  45.                 } catch (IOException e) {
  46.                         e.printStackTrace();
  47.                 }
  48.         }

  49.         public static void main(String[] args) {
  50.                 if (file.exists()) {                            //如果配置文件存在,则从配置文件中载入启动参数
  51.                         proxy.readFile();
  52.                 } else {                                        //如果配置文件不存在,则创建配置文件,然后使用默认的参数来启动
  53.                         proxy.createFile();
  54.                 }
  55.                 ProxyServer server = new ProxyServer(host, port);
  56.                 server.start();
  57.         }
  58. }
复制代码

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
2 [报告]
发表于 2013-06-21 22:59 |只看该作者
这是用来监听代理端口的类
  1. package com.fangzhaoguo.proxy;

  2. import java.io.IOException;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. import java.util.concurrent.ExecutorService;
  6. import java.util.concurrent.Executors;

  7. public class ProxyServer {
  8.         private static ServerSocket serverSocket;
  9.         private boolean isAlive = true;
  10.         private String host = null;
  11.         private int port = 0;

  12.         public ProxyServer(final String host, final int port) {
  13.                 try {
  14.                         this.host = host;
  15.                         this.port = port;
  16.                         serverSocket = new ServerSocket(this.port);
  17.                 } catch (IOException e) {
  18.                         e.printStackTrace();
  19.                 }
  20.         }

  21.         public void start() {
  22.                 ExecutorService service = Executors.newFixedThreadPool(20);   //创建线程池
  23.                 while (isAlive) {
  24.                         try {
  25.                                 Socket socket = serverSocket.accept();
  26.                                 service.execute(new ProxyConnect(host, socket));    //使用线程池中的线程处理任务
  27.                         } catch (IOException e) {
  28.                                 e.printStackTrace();
  29.                         }
  30.                 }
  31.                 try {
  32.                         serverSocket.close();
  33.                 } catch (IOException e) {
  34.                         e.printStackTrace();
  35.                 }
  36.         }

  37.         public void close() {
  38.                 isAlive = false;
  39.         }
  40. }
复制代码

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
3 [报告]
发表于 2013-06-21 23:03 |只看该作者
这是存放视频数据内容的表
  1. create table if not exists Data
  2. (
  3.         id int not null auto_increment,
  4.         name varchar(100) not null,
  5.         data blob not null,
  6.         size int not null,
  7.         log timestamp not null default now(),
  8.         primary key (id)
  9. );
复制代码
id是自动增长的序号,以免数据其他字段的重复导致数据被误刷新
name是视频片断的名称
data是视频片断的数据内容
size是数据片断的大小
log是数据写入日期

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
4 [报告]
发表于 2013-06-21 23:05 |只看该作者
这是存放视频名称的表
  1. create table if not exists Information
  2. (
  3.         id int not null auto_increment,
  4.         url char(100) not null,
  5.         log timestamp not null default now(),
  6.         primary key (id)
  7. );
复制代码
id是自动增长的序号
url是视频的名称,旧版本中使用的是url地址,因此保留了这个名称
log是视频最后一次被浏览的日期

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
5 [报告]
发表于 2013-06-21 23:08 |只看该作者
这是用来关联视频名称和视频片断的表
  1. create table if not exists DataIndex
  2. (
  3.         file_id int not null,
  4.         block_id int not null,
  5.         primary key (file_id,block_id),
  6.         foreign key(file_id) references Information(id),
  7.         foreign key(block_id) references Data(id)
  8. );
复制代码
file_id是视频名称的id,外键,关联至视频名称表Information的id字段
block_id是视频片断的id,外键,关联至视频数据内容表 Data的id字段

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
6 [报告]
发表于 2013-06-21 23:09 |只看该作者
这是视频名称表Information上的存储函数,用来插入新行并且返回id
  1. CREATE function fun_Information(address char(100))
  2. RETURNS int
  3. BEGIN
  4.         DECLARE file_id int;
  5.         select count(*) into file_id from Information where url=address;
  6.         if file_id < 1  then
  7.                 insert into Information(url) values(address);
  8.         end if;
  9.         select id into file_id from Information where url=address;
  10.         return file_id;
  11. END
复制代码

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
7 [报告]
发表于 2013-06-21 23:10 |只看该作者
这是视频数据内容表Data上的存储函数,用来插入新行并且返回id
  1. CREATE FUNCTION fun_Data(nValue char(100),dValue blob,sValue int,fValue int)
  2. RETURNS int
  3. BEGIN
  4.         DECLARE bValue int;
  5.         select count(*) into @Value from Data where name=nValue;
  6.         if @Value<1  then
  7.                 insert into Data(name,data,size) values(nValue,dValue,sValue);
  8.         end if;
  9.         select id into bValue from Data where name=nValue;
  10.         select count(*) into @Value from DataIndex inner join Data on Data.id=DataIndex.block_id where Data.name=nValue and DataIndex.file_id=fValue;
  11.         if @Value<1  then
  12.                 insert DataIndex(file_id,block_id) values(fValue,bValue);
  13.         end if;       
  14.         return bValue;
  15. END
复制代码

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
8 [报告]
发表于 2013-06-21 23:11 |只看该作者
接下来就是最关键的内容,也就是客户端和代理服务器之间通信的函数了,问题就出在这儿,代理服务器只能接受并且正常返回第一条请求,剩下的就都出问题了

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
9 [报告]
发表于 2013-06-21 23:15 |只看该作者
ProxyConnect 使用了 Runnable
run()如下所示,我自己对这一块儿也很糊涂,关键就是http请求和响应的问题
  1. public void run() {
  2.                 int file_id = -1;
  3.                 int[] block_id = null;
  4.                 String filename = this.read();
  5.                 String sql = "{?=call fun_Information(?)}";
  6.                 file_id = database.Rrocedure(sql, filename);
  7.                 sql = "update Information set log=now() where id=" + file_id;
  8.                 database.Write(sql);

  9.                 while (isAlive) {
  10.                         sql = "select Data.id,Data.size from Data inner join DataIndex on Data.id=DataIndex.block_id inner join Information on Information.id=DataIndex.file_id where Information.id="
  11.                                         + file_id + " and Data.name='" + filename + "';";
  12.                         rs = database.Read(sql);
  13.                         try {
  14.                                 if (rs.next()) {
  15.                                         block_id = new int[rs.getRow()];
  16.                                         rs.beforeFirst();
  17.                                         int i = 0, length = 0;
  18.                                         while (rs.next()) {
  19.                                                 block_id[i] = rs.getInt(1);
  20.                                                 length += rs.getInt(2);
  21.                                                 i++;
  22.                                         }
  23.                                         rs.close();
  24.                                         database.ResultSetClose();
  25.                                         this.SendHead(length);
  26.                                         for (i = 0; i < block_id.length; i++) {
  27.                                                 this.WorkDB(block_id[i]);
  28.                                                 try {
  29.                                                         out.flush();
  30.                                                 } catch (IOException e) {
  31.                                                         e.printStackTrace();
  32.                                                 }
  33.                                         }
  34.                                 } else {
  35.                                         rs.close();
  36.                                         database.ResultSetClose();
  37.                                         this.WorkNet(file_id, filename);
  38.                                 }
  39.                         } catch (SQLException e) {
  40.                                 e.printStackTrace();
  41.                         }
  42.                         filename = this.read();
  43.                 }

  44.                 this.close();
  45.         }
复制代码

论坛徽章:
19
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-09-18 15:15:15CU大牛徽章
日期:2013-05-20 10:46:44CU大牛徽章
日期:2013-05-20 10:46:38CU大牛徽章
日期:2013-05-20 10:46:31CU大牛徽章
日期:2013-05-20 10:46:25CU大牛徽章
日期:2013-05-20 10:46:18CU大牛徽章
日期:2013-04-17 11:19:51CU大牛徽章
日期:2013-04-17 11:19:42CU大牛徽章
日期:2013-04-17 11:19:37CU大牛徽章
日期:2013-04-17 11:19:32CU大牛徽章
日期:2013-04-17 11:19:28
10 [报告]
发表于 2013-06-21 23:24 |只看该作者
这是从web服务器读取数据的函数,并且对数据进行处理
  1. private String read() {
  2.                 String buffer = null;
  3.                 System.out.println("I am the " + Thread.currentThread().getId() + "\t"
  4.                                 + Thread.currentThread().getName());      //用来显示该线程是第几个线程
  5.                 try {
  6.                         do {
  7.                                 buffer = in.readLine();
  8.                                 if (buffer.startsWith("Connection: ")) {                                         //如果是以Connection开头,则记录时Keep-Alive还是Close
  9.                                         connection = buffer.substring(buffer.indexOf(" ") + 1);
  10.                                         System.out.println(connection);
  11.                                         if (connection.equals("close")) {
  12.                                                 isAlive = false;
  13.                                         }
  14.                                 }
  15.                                 if (buffer.startsWith("null")) {
  16.                                         isAlive = false;
  17.                                 }
  18.                         } while (!buffer.startsWith("GET") && isAlive);
  19.                         buffer = buffer.substring(5, buffer.lastIndexOf(" "));
  20.                 } catch (IOException e) {
  21.                         e.printStackTrace();
  22.                 }
  23.                 return buffer;
  24.         }
复制代码
System.out.println("I am the " + Thread.currentThread().getId() + "\t"+ Thread.currentThread().getName());     
用来显示该线程是第几个线程,之前对浏览器的请求有疑惑,因此加入了调试代码


if (buffer.startsWith("Connection: ")) {                                       
                                        connection = buffer.substring(buffer.indexOf(" ") + 1);
                                        System.out.println(connection);
                                        if (connection.equals("close")) {
                                                isAlive = false;
                                        }
如果是以Connection开头,则记录时Keep-Alive还是Close
但是我还是对这个Keep-Alive和Close的区别不是很理解,Close好像是本次会话结束之后就关闭的意思
而且使用buffer.substring(buffer.indexOf("HTTP"));检索的时候会看到有一会儿是HTTP 1.0 有些时候是HTTP 1.1
更诡异的是User-Agent字段,有些时候是GPAC/0.5.0-rev4065,有些时候是 Lavf52.33.0,用的是同一个播放器
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP