面向Socket编程,实现Java客户端向服务器发送http请求

 

文章目录

 


前言

 

作为一个合格的程序员,不能不懂网络编程,说到网络编程,Socket编程作为网络通信的底层API,对我们了解那些网络框架的底层原理,大有助益。


 

一、Socket是什么?

Socket是TCP/IP协议中应用层和传输层之间的媒介,Socket本质上就是对TCP/IP的运用进行了一次封装,以便供应用层使用。应用程序直接使用Socket API 就可以进行通信。

二、代码实现通信

本文主要是用Java客户端向服务器发送请求,获取响应信息。Socket的客户端和服务器之间的连接和TCP连接的“三次招手”差不多。客户端和服务器是通过字节流的形式就行通信的。

1.先创建一个HttpResponse类,以存放响应信息的各个部分。

public class HttpResponse {
    private String url;
    private String header;
    private String body;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getHeader() {
        return header;
    }

    public void setHeader(String header) {
        this.header = header;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    @Override
    public String toString() {
        return "HttpResponse{" +
                "url='" + url + '\'' +
                ", header='" + header + '\'' +
                ", body='" + body + '\'' +
                '}';
    }
}

 

2.实现客户端通信

public class TcpClient {
    public static void main(String[] args) throws IOException {
        Socket socket = null;
        OutputStream out = null;
        InputStream in = null;
        ByteArrayOutputStream byteOut = null;
        try {
            //服务器ip地址和端口
            socket = new Socket("www.baidu.com",80);
            //输出流
            out = socket.getOutputStream();
            //构造http请求
            StringBuilder builder = new StringBuilder();
            //header信息
            Map<String,String> map = new HashMap<>();
            //文本类型
            map.put("Content-Type","text/html;charset=utf-8");
            //保持连接
            map.put("Connection","keep-alive");
            map.put("Host","www.baidu.com");
            //请求行
            builder.append("GET / HTTP/1.1\r\n");
            //请求头部
            for(Map.Entry<String,String> entry:map.entrySet()){
                builder.append(entry.getKey() + ":" +entry.getValue() + "\r\n");
            }
            //请求空行
            builder.append("\r\n");
            out.write(builder.toString().getBytes());
            //输入流
            in = socket.getInputStream();
            byteOut = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = in.read(bytes)) != -1){
                //写入新建流中
                byteOut.write(bytes,0,len);
            }
            //以响应空行为标志,将响应信息分为两个部分
            String[] str = new String(byteOut.toByteArray()).split("\r\n\r\n");
            //以空行为标志,将响应行和响应头部分开
            String[] urlAndHeader = str[0].split("\r\n");
            HttpResponse httpResponse = new HttpResponse();
            //响应行
            httpResponse.setUrl(urlAndHeader[0]);
            StringBuilder headers = new StringBuilder();
            for (int i = 1; i < urlAndHeader.length; i++){
                //拼接响应头部
                headers.append(urlAndHeader[i] + "\r\n");
            }
            //响应头部
            httpResponse.setHeader(headers.toString());
            //响应文本
            httpResponse.setBody(str[1]);
            System.out.println(httpResponse.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (byteOut != null){
                byteOut.close();
            }
            if (out != null){
                out.close();
            }
            if (in != null){
                in.close();
            }
            if (socket != null){
                //释放资源
                socket.close();
            }
        }
    }
}

总结

这就是实现Socket通信的一个简单例子,我们经常使用的开源框架,如Java提供的HttpURLConnection与 HttpClient,以及OKHttp网络框架底层都是基于Socket编程实现的。因此了解Socket编程是很有必要的。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值