socket通过http上传下载

来源:互联网 发布:万方数据库的免费入口 编辑:程序博客网 时间:2024/06/06 15:03

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