socket通过http上传下载

原创 2016年05月31日 10:54:20

直接上代码,涉及http消息格式问题参考其他资料

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by chao.zeng on 2016/5/30.
 */
public class HttpClient {
    private Socket socket;
    private StringBuilder header=new StringBuilder();
    private List<StringBuilder> bodys=new ArrayList<StringBuilder>();
    private List<StringBuilder> bodyHeadersFile=new ArrayList<StringBuilder>();
    private long contentLength=0;
    private String boundary="----WebKitFormBoundaryUalLNdJ5BjmXlLhv";
    public static void  main(String[] args) throws IOException {
        HttpClient client=new HttpClient("localhost",8080);
        Map<String,String> params=new HashMap<String,String>();
        params.put("id","10030");
        params.put("xx","xxoo");
        Map<String,String> files=new HashMap<String,String>();
        files.put("name1","d:\\deerway.zip");
        files.put("name2","d:\\deerway2.zip");
        client.upload("/cloudolp.dc/deviceApi/cameraupload",params,files);

        Map<String,String> params2=new HashMap<String,String>();
        params2.put("id","10030");
        params2.put("name","name1");
        client=new HttpClient("localhost",8080);
        client.download("/cloudolp.dc/deviceApi/cameradownload",params2,"d:\\xx.zip");
    }
    public HttpClient(String host,int port) throws IOException {
        socket=new Socket(host,port);
    }
    private void setHeader(){
        /**
         * 写入请求行
         * 第一个参数为方法,POST,GET等
         * 第二个是URL地址
         * 第三个是HTTP版本,有HTTP/1.0,HTTP/1.1,HTTP/2.0,
         */
        header.append("POST /cloudolp.dc/deviceApi/cameraupload HTTP/1.1\r\n");
        /**
         * 写入请求头,请求头和请求体之间需要一行空行分割
         * Host:参数必须要有,不然服务器不接收
         * Content-Type:因为是上传文件,此值必须为multipart/form-data,后面的boundary是各个请求体参数的分割符,详情参考http规范
         * 每个头和体之间要有空行分隔'\r\n'
         */
        header.append("Host: localhost:8088\r\n");
        header.append("Connection:Keep-Alive\r\n");
        header.append("Content-Length:"+contentLength+"\r\n");
        header.append("Content-Type:multipart/form-data; boundary="+boundary+"\r\n");
        header.append("\r\n");
    }
    public void upload(String url,Map<String,String> params,Map<String,String> files) throws IOException {
        /**
         * 计算消息体长度,因为消息头需要传Content-Length,即消息体长度
         * 因为是multipart/form-data,所以消息体会包含很多部分,每部分用分割符boundary分开(其实是两个'-'加上头上定义的分隔符)
         */
        /**
         * 普通参数
         */
        for(Map.Entry<String,String> entry:params.entrySet()){
            StringBuilder body=new StringBuilder();
            body.append("--"+boundary+"\r\n");
            body.append("Content-Disposition: form-data; name=\""+entry.getKey()+"\"\r\n");
            body.append("\r\n");
            body.append(entry.getValue());
            body.append("\r\n");
            bodys.add(body);
            contentLength+=body.toString().getBytes().length;
        }
        /**
         * 文件参数
         */
        for(Map.Entry<String,String> entry:files.entrySet()){
            StringBuilder bodyheader=new StringBuilder();
            bodyheader.append("--"+boundary+"\r\n");
            bodyheader.append("Content-Disposition: form-data; name=\""+entry.getKey()+"\"; filename=\""+entry.getValue()+"\"\r\n");
            bodyheader.append("\r\n");
            bodyHeadersFile.add(bodyheader);
            contentLength+=bodyheader.toString().getBytes().length;
            File file=new File(entry.getValue());
            contentLength+=file.length()+2;
        }
        StringBuilder endboundary=new StringBuilder();
        endboundary.append("--");
        endboundary.append(boundary);
        endboundary.append("--"+"\r\n");

        contentLength+=endboundary.toString().getBytes().length;
        setHeader();
        OutputStream out=socket.getOutputStream();
        out.write(header.toString().getBytes());

        for(StringBuilder body:bodys){
            out.write(body.toString().getBytes());
        }
        int i=0;
        for(Map.Entry<String,String> entry:files.entrySet()){
            out.write(bodyHeadersFile.get(i++).toString().getBytes());//写入文件头
            File file=new File(entry.getValue());
            //写入文件
            InputStream input=new FileInputStream(file);
            byte[] bs=new byte[8192];
            int length=input.read(bs);
            while(length!=-1){
                out.write(bs,0,length);
                length=input.read(bs);
            }
            out.write("\r\n".getBytes());//写入空行
        }
        //写入结束标志
        out.write(endboundary.toString().getBytes());

    }

    public void download(String url,Map<String,String> params,String dest) throws IOException {
        StringBuilder urlsb=new  StringBuilder();
        urlsb.append(url);
        urlsb.append("?");
        for(Map.Entry<String,String> entry:params.entrySet()){
            urlsb.append(entry.getKey());
            urlsb.append("=");
            urlsb.append(entry.getValue());
            urlsb.append("&");
        }
        urlsb.deleteCharAt(urlsb.length()-1);
        StringBuilder sb=new StringBuilder();
        sb.append("GET "+urlsb.toString()+" HTTP/1.1\r\n");
        sb.append("Host: localhost:8088\r\n");
        sb.append("Connection:Keep-Alive\r\n");
        sb.append("\r\n");
        socket.getOutputStream().write(sb.toString().getBytes());
        InputStream input=socket.getInputStream();
        String line=readLine(input);
        //第一行为响应行,包含状态码
        String[] reslines=line.split(" ");
        if(!reslines[1].equals("200")){
            System.out.println("响应出错:状态码为"+reslines[1]);
            return;
        }
        while(!line.equals("")){
            System.out.println(line);
            line=readLine(input);
        }
        OutputStream out=new FileOutputStream(dest);
        int length=Integer.parseInt(readLine(input),16);
        while(length!=0){
            byte[] content=new byte[length];
            input.read(content);
            out.write(content,0,length);
            input.read();//读入'\r'
            input.read();//读入'\n'
            length=Integer.parseInt(readLine(input),16);
        }
    }
    private String readLine(InputStream input) throws IOException {
        StringBuilder sb=new StringBuilder();
        char c=(char)input.read();
        while(c!='\r'){
            sb.append(c);
            c=(char)input.read();
        }
        input.read();
        return sb.toString();
    }
}


JAVA通信(1)-- 使用Socket实现文件上传与下载

客户端/** * 文件上传客户端 * * @author chen.lin * */ public class UploadClient extends JFrame { /** ...
  • lovoo
  • lovoo
  • 2016年04月21日 14:41
  • 2879

windows学习记录之MFC通过URL上传下载文件

HTTP四种常见的POST提交数据方式:HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 ...
  • xiaowenliuwen
  • xiaowenliuwen
  • 2016年03月24日 11:30
  • 2240

socket http文件下载器c语言实现

socket真是一个神奇的东西,可以说是另外一扇大门, 蕴藏着很多有趣的东西, 本文就介绍如何使用c语言使用socket实现一个http文件下载器.下载分为以下几个过程 解析出下载地址中的域名和文件名...
  • xiongyangg
  • xiongyangg
  • 2016年02月29日 18:52
  • 5931

Java文件传输工具(SFTP、FTP、HTTP上传下载)

  • 2017年05月17日 15:53
  • 33KB
  • 下载

使用线程池实现的Http上传下载实现

  • 2013年03月17日 11:56
  • 55KB
  • 下载

Http Servlet文件上传下载

  • 2011年09月05日 15:29
  • 403KB
  • 下载

http上传下载功能的一个段小代码程序

  • 2009年06月18日 11:36
  • 8KB
  • 下载

http上传下载C++代码实现

  • 2017年05月12日 15:17
  • 11KB
  • 下载

socket上传下载

  • 2015年05月30日 10:59
  • 53KB
  • 下载

miniFTP SOCKET通信 上传下载文件

  • 2011年12月11日 21:30
  • 25KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:socket通过http上传下载
举报原因:
原因补充:

(最多只允许输入30个字)