关闭

socket通过http上传下载

标签: sockethttp 上传 下载
395人阅读 评论(0) 收藏 举报
分类:

直接上代码,涉及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();
    }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:39255次
    • 积分:714
    • 等级:
    • 排名:千里之外
    • 原创:30篇
    • 转载:9篇
    • 译文:2篇
    • 评论:2条
    文章分类
    最新评论