`
moshangchenzi
  • 浏览: 51631 次
  • 性别: Icon_minigender_1
  • 来自: 南宁
社区版块
存档分类
最新评论

JDK6.0学习笔记(十八)大文件传输-可靠传输

阅读更多
  1. /**
  2.  * 大文件传输-可靠传输
  3.  * 与浏览器表单结合,控制机制由服务器端负责,
  4.  * 客户端(静态网页)只需向服务器端上传文件即可
  5.  * 将读取的数据及时的写入文件系统,解决服务器端内存的溢出
  6.  * 必须设置表单的ENCTYPE属性为 multipart/form-data(传输文件内容)
  7.  * */
  8. import java.io.*;
  9. import java.net.*;
  10. public class TcpServer {
  11.     public static void main(String[] args) throws IOException {
  12.         ServerSocket serverSocket = new ServerSocket(9080);//监听9080断口,一旦接入一个新连接,
  13.             //将立刻创建一个子线程处理连接,目的是进可能快,尽可能多的接受客户端的请求
  14.         System.out.println("TcpServer在9080端口上侦听......");
  15.         while (true) {
  16.             try {
  17.                 Socket socket = serverSocket.accept();
  18.                 System.out.println("建立一个连接...");
  19.                 // 创建TCP请求处理线程
  20.                 RequestThread request = new RequestThread(socket);
  21.                 request.start();
  22.             } catch (Exception e) {
  23.                 e.printStackTrace();
  24.             }
  25.         }
  26.     }
  27. }
 
  1. /**
  2.  * 子线程RequestThread类把主线程传来的Socket对象继续传递给SocketRequest功能类处理
  3.  * 
  4.  * 
  5.  * */
  6. import java.io.*;
  7. import java.net.*;
  8. public class RequestThread extends Thread {// 子线程RequestThread类继承Thred,多线程
  9.     Socket socket = null;
  10.     public RequestThread(Socket socket) {
  11.         this.socket = socket;
  12.     }
  13.     public void run() {
  14.         SocketRequest socketRequest = new SocketRequest(this.socket);// 功能类SocketRequest实例
  15.         socketRequest.readData();
  16.     }
  17. }
暗暗
  1. /**
  2.  * 功能类SocketRequest 
  3.  * */
  4. import java.io.*;
  5. import java.net.*;
  6. public class SocketRequest {
  7.     private Socket socket = null;
  8.     private InputStream input = null;
  9.     private String uri;
  10.     private StringBuffer request = new StringBuffer(); // 用于保存所有内容
  11.     private int CONTENT_LENGTH = 0// 实际包内容数据长
  12.     private boolean bePost = false;
  13.     private boolean beHttpResponse = false;
  14.     private boolean beChucked = false;
  15.     private boolean beGet = false;
  16.     private byte crlf13 = (byte13// '\r'
  17.     private byte crlf10 = (byte10// '\n'
  18.     private String requestFile = System.currentTimeMillis() + "";
  19.     public SocketRequest(Socket socket) {
  20.         try {
  21.             this.socket = socket;
  22.             this.input = socket.getInputStream();
  23.         } catch (IOException ioe) {
  24.             ioe.printStackTrace();
  25.         }
  26.     }
  27.     public void readData() {
  28.         // 解析 获得InputStream的数据
  29.         ReadHeader(); // 头部
  30.         if (beChucked) // 为Chucked
  31.         {
  32.             int ChuckSize = 0;
  33.             while ((ChuckSize = getChuckSize()) > 0// 多个Chucked
  34.             {
  35.                 readLenData(ChuckSize + 2);// 读取定长数据
  36.             }
  37.             readLenData(2); // 最后的2位
  38.         }
  39.         if (CONTENT_LENGTH > 0) {
  40.             readBody(CONTENT_LENGTH);// 读取报文体数据
  41.         }
  42.         try {
  43.             this.socket.close();
  44.         } catch (Exception e) {
  45.             e.printStackTrace();
  46.         }
  47.     }
  48.     private void readLenData(int size) // 读取定长数据
  49.     {
  50.         int readed = 0// 已经读取数
  51.         try {
  52.             int available = 0// 可读数
  53.             if (available > (size - readed))
  54.                 available = size - readed;
  55.             while (readed < size) {
  56.                 while (available == 0) {
  57.                     // 等到有数据可读
  58.                     available = input.available(); // 可读数
  59.                 }
  60.                 if (available > (size - readed))
  61.                     available = size - readed; // 剩余数
  62.                 if (available > 2048)
  63.                     available = 2048// size-readed--剩余数
  64.                 byte[] buffer = new byte[available];
  65.                 int reading = input.read(buffer);
  66.                 request = request.append(new String(buffer, 0, reading));
  67.                 readed += reading; // 已读字符
  68.             }
  69.         } catch (IOException e) {
  70.             System.out.println("Read readLenData Error!");
  71.         }
  72.     }
  73.     private void readBody(int size) {
  74.         int readed = 0// 已经读取数
  75.         try {
  76.             int available = 0// 可读数
  77.             if (available > (size - readed))
  78.                 available = size - readed;
  79.             while (readed < size) {
  80.                 while (available == 0) {
  81.                     // 等到有数据可读
  82.                     available = input.available(); // 可读数
  83.                 }
  84.                 if (available > (size - readed))
  85.                     available = size - readed; // 剩余数
  86.                 if (available > 2048)
  87.                     available = 2048// size-readed--剩余数
  88.                 byte[] buffer = new byte[available];
  89.                 int reading = input.read(buffer);
  90.                 // request=request.append(new String(buffer,0,reading));
  91.                 if (!new File(this.requestFile).exists())
  92.                     this.createFile(this.requestFile);
  93.                 this.writeIntoFile(this.requestFile, buffer, available, readed);
  94.                 readed += reading; // 已读字节数
  95.             }
  96.         } catch (IOException e) {
  97.             System.out.println("Read Body Error!");
  98.         }
  99.     }
  100.     private void ReadHeader() // 读取头部 并获得大小
  101.     {
  102.         byte[] crlf = new byte[1];
  103.         int crlfNum = 0// 已经连接的回车换行数 crlfNum=4为头部结束
  104.         try {
  105.             while (input.read(crlf) != -1// 读取头部
  106.             {
  107.                 if (crlf[0] == crlf13 || crlf[0] == crlf10) {
  108.                     crlfNum++;
  109.                 } else {
  110.                     crlfNum = 0;
  111.                 }
  112.                 request = request.append(new String(crlf, 01));
  113.                 if (crlfNum == 4)
  114.                     break;
  115.             }
  116.         } catch (IOException e) {
  117.             System.out.println("Read Http Header Error!");
  118.             return;
  119.         }
  120.         String tempStr = (new String(request)).toUpperCase();
  121.         // 这里只处理了GET与POST方法,其它的其它类型 暂不支持
  122.         String strMethod = tempStr.substring(04);
  123.         if (strMethod.equals("GET ")) {
  124.             beGet = true;
  125.         } else if (strMethod.equals("POST")) {
  126.             bePost = true;
  127.             getContentlen_Chucked(tempStr);
  128.         } else {
  129.             System.out.println("不支持的HTTP包类型");
  130.         }
  131.     }
  132.     private void getContentlen_Chucked(String tempStr) // 获得长度 CONTENT-LENGTH 或
  133.     // 是否为CHUNKED型
  134.     {
  135.         String ss1 = "CONTENT-LENGTH:";
  136.         String ss2 = new String("TRANSFER-ENCODING: CHUNKED");
  137.         int clIndex = tempStr.indexOf(ss1);
  138.         int chuckIndex = tempStr.indexOf(ss2); // 为CHUNKED型
  139.         byte requst[] = tempStr.getBytes();
  140.         if (clIndex != -1) {
  141.             // 从clIndex+1起至\r\n
  142.             StringBuffer sb = new StringBuffer();
  143.             for (int i = (clIndex + 16);; i++) {
  144.                 if (requst[i] != (byte13 && requst[i] != (byte10) {
  145.                     sb.append((char) requst[i]);
  146.                 } else
  147.                     break;
  148.             }
  149.             CONTENT_LENGTH = Integer.parseInt(sb.toString());
  150.         }
  151.         if (chuckIndex != -1)
  152.             beChucked = true;
  153.     }
  154.     private int getChuckSize() // Chuck大小
  155.     {
  156.         byte[] crlf = new byte[1];
  157.         StringBuffer sb1 = new StringBuffer();
  158.         int crlfNum = 0// 已经连接的回车换行数 crlfNum=4为头部结束
  159.         try {
  160.             while (input.read(crlf) != -1// 读取头部
  161.             {
  162.                 if (crlf[0] == crlf13 || crlf[0] == crlf10) {
  163.                     crlfNum++;
  164.                 } else {
  165.                     crlfNum = 0;
  166.                 }
  167.                 sb1.append((char) crlf[0]);
  168.                 request = request.append(new String(crlf, 01));
  169.                 if (crlfNum == 2)
  170.                     break;
  171.             }
  172.         } catch (IOException e) {
  173.             System.out.println("Read Http Package Error!");
  174.             return 0;
  175.         }
  176.         return Integer.parseInt((sb1.toString()).trim(), 16); // 16进制
  177.     }
  178.     private void writeIntoFile(String filePath, byte[] bytes, int realLength,
  179.             int finishedFileSize) throws IOException {
  180.         File newFile = new File(filePath);
  181.         RandomAccessFile raf = new RandomAccessFile(newFile, "rw");
  182.         raf.seek(finishedFileSize);
  183.         raf.write(bytes, 0, realLength);
  184.         raf.close();
  185.     }
  186.     private void createFile(String filePath) throws IOException {
  187.         File newFile = new File(filePath);
  188.         RandomAccessFile raf = new RandomAccessFile(newFile, "rw");
  189.         raf.close();
  190.     }
  191. }

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics