socket通过http上传下载

直接上代码,涉及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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值