JAVA写HTTP代理服务器-socket实现

这篇具有很好参考价值的文章主要介绍了JAVA写HTTP代理服务器-socket实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、HTTP代理服务器

HTTP代理服务器是一个中间服务器,它负责接收客户端的HTTP请求,然后将请求转发给目标服务器,并将目标服务器返回的响应返回给客户端。代理服务器可以处理各种HTTP请求,如GET、POST、PUT、DELETE等,并可以处理HTTPS请求。在开发Web应用程序时,使用代理服务器可以隐藏后端服务器的真实IP地址,增强安全性。

二、Java Socket

Java Socket是Java网络编程中的重要部分,它提供了一种使用TCP协议进行网络通信的方式。使用Java Socket,我们可以创建一个套接字,连接到远程主机,并通过套接字发送和接收数据。

三、思路

创建SocketServer监听端口,根据http请求头信息建立代理服务器与目标服务器的连接,然后通过httpclient转发请求数据,然后将目标服务器的响应消息通过socket连接返回给客户端。

四、示例代码

创建socket监听

/**
 * @author Charles
 * @module socket
 * @since 2023/8/3 12:03
 */
public class InitProxyServer {

    public void startServer(int port) {
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            while (true) {
                //The server socket
                Socket socket = serverSocket.accept();
                new ProxyServer(socket).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

请求转发处理

@Override
public void run() {
    try {
        StringBuffer res = new StringBuffer();
        String content = "";
        res.append("HTTP/1.1 200 ok \r\n");
        res.append("Content-Type:application/json;charset=utf-8; \r\n");
        // 解析请求地址  http(s)://serviceName/路径?userName=xxx&passWord=xxx&other=xxx
        RequestData read = Request.read(this.input);
        if(read == null){
            res.append("Content-Length:" + content.getBytes().length + "\r\n");
            res.append("\r\n");
            res.append(content);
            out.write(res.toString().getBytes());
            out.flush();
            return;
        }
        // 用户鉴权
        Authenticator authenticator = new Authenticator();
        authenticator.authenticateByMemory(read.getServiceName(), read.getUserName(), read.getPassword());
        // 服务路由 根据服务名获取实际的服务地址和端口,这里处理的是http请求
        ServiceRegistration serviceRegistration = new ServiceRegistration();
        String target = serviceRegistration.getTarget(read.getServiceName());
        // 使用jdk的http客户端发起真实的请求
        String body = "";
        if(read.getMethodType().contains(GET)){
            body = HttpUtil.createGet(target + read.getRequestPath()).body(read.getParamBody()).execute().body();
        }
        if(read.getMethodType().contains(POST)){
            body = HttpUtil.createPost(target + read.getRequestPath()).body(read.getParamBody()).execute().body();
        }
        // 响应目标服务器消息
        content = body;
        res.append("Content-Length:" + content.getBytes().length + "\r\n");
        res.append("\r\n");
        res.append(content);
        out.write(res.toString().getBytes());
        out.flush();
    }catch (Exception e){
        System.out.println("服务器代理异常!");
        e.printStackTrace();
    }finally {
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

其他辅助类

/**
 * 用户鉴权判断
 *
 * @param serviceName 代理的服务名称
 * @param userName 用户名
 * @param password 密码
 */
public void authenticateByMemory(String serviceName, String userName, String password){
    Map<String, String> service = memoryUser.get(serviceName);
    if(Objects.isNull(service)){
        throw new RuntimeException("服务不存在");
    }
    String user = service.get(userName);
    if(Objects.isNull(user)){
        throw new RuntimeException("用户不存在");
    }else if(!user.equals(password)){
        throw new RuntimeException("密码错误");
    }
}
/**
 * 解析请求头
 *
 * @param input
 * @return
 */
public static RequestData read(InputStream input) {
    StringBuilder stringBuilder = new StringBuilder();
    try {
        byte[] bytes = new byte[1024];
        while (input.available() != 0) {
            input.read(bytes);
            String str = new String(bytes, Charset.forName("utf-8"));
            stringBuilder.append(str);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    String accept = stringBuilder.toString();
    if("".equals(accept)){
        return null;
    }
    String[] split = accept.split("\\r\\n");
    if(!split[0].contains(HTTP)){
        throw new RuntimeException("错误的请求");
    }else if(!split[0].contains(GET) && !split[0].contains(POST)){
        throw new RuntimeException("错误的请求方式");
    }
    String[] data = split[0].split(" ");
    if(!data[1].contains("?")){
        throw new RuntimeException("未携带用户参数");
    }
    RequestData requestData = new RequestData();
    requestData.setMethodType(data[0].replace("/", ""));
    requestData.setRequestPath(data[1].substring(data[1].indexOf("/", 1), data[1].indexOf("?")));
    requestData.setServiceName(data[1].substring(1, data[1].indexOf("/", 1)));
    String auth = data[1].substring(data[1].indexOf("?") + 1);
    requestData.setParamBody(auth);
    if(Objects.isNull(auth) || !auth.contains(USERNAME) || !auth.contains(PASSWORD)){
        throw new RuntimeException("未携带用户消息");
    }
    String[] keyValue = auth.split("&");
    for (int i = 0; i < keyValue.length; i++) {
        if(keyValue[i].contains(USERNAME)){
            requestData.setUserName(keyValue[i].replace(USERNAME, "").replace("=", ""));
        }
        if(keyValue[i].contains(PASSWORD)){
            requestData.setPassword(keyValue[i].replace(PASSWORD, "").replace("=", ""));
        }
    }
    return requestData;
}

五、测试效果

通过postman请求本地服务代理到远程目标服务上。

java 代理服务器,java知识体系,java,http,开发语言,服务器,后端,网络,网络协议

java 代理服务器,java知识体系,java,http,开发语言,服务器,后端,网络,网络协议文章来源地址https://www.toymoban.com/news/detail-779139.html

到了这里,关于JAVA写HTTP代理服务器-socket实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java网络编程】基于UDP-Socket 实现客户端、服务器通信

    ​ 哈喽,大家好~我是你们的老朋友: 保护小周ღ   本期为大家带来的是网络编程的 UDP Socket 套接字,基于 UDP协议的 Socket 实现客户端服务器通信 ,Socket 套接字可以理解为是,传输层给应用层提供的一组 API,如此程序,确定不来看看嘛~~ 本期收录于博主的专栏 : JavaEE_保

    2024年02月02日
    浏览(71)
  • HTTP代理服务器的设计与实现

    一、前言 这个实验挺麻烦的,本来就只有一周时间,等我开始着手准备的时候,也就剩两三天了,也没什么心情自己重头开打代码,于是就找了大佬的代码借鉴了一下,在验收之前处理完了所有的bug。不过,我觉得这个实验还是最好自己慢慢想,想到问题再去搜索,能收获到

    2023年04月13日
    浏览(51)
  • Java【网络编程2】使用 TCP 的 Socket API 实现客户端服务器通信(保姆级教学, 附代码)

    📕各位读者好, 我是小陈, 这是我的个人主页 📗小陈还在持续努力学习编程, 努力通过博客输出所学知识 📘如果本篇对你有帮助, 烦请点赞关注支持一波, 感激不尽 📙 希望我的专栏能够帮助到你: JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统

    2024年02月05日
    浏览(65)
  • HTTP 代理服务器的设计与实现(C++)

    设计并实现一个基本 HTTP 代理服务器。要求在指定端口(例如 8080)接收来自客户的 HTTP 请求并且根据其中的 URL 地址访问该地址 所指向的 HTTP 服务器(原服务器),接收 HTTP 服 务器的响应报文,并 将响应报文转发给对应的客户进行浏览。 设计并实现一个支持 Cache 功能的

    2024年02月03日
    浏览(42)
  • 哈工大计算机网络实验一——HTTP代理服务器的设计与实现

    1. 设计并实现一个基本 HTTP 代理服务器。 要求在指定端口接收来自客户的 HTTP 请求并且根据其中的 URL 地址访问该地址所指向的 HTTP 服务器(原服务器),接收 HTTP 服务器的响应报文,并将响应报文转发给对应的客户进行浏览。 2. 设计并实现一个支持 Cache 功能的 HTTP 代理服

    2024年02月22日
    浏览(49)
  • 哈工大计算机网络实验一-HTTP代理服务器的设计与实现

    当客户在浏览器中设置好Proxy Server后,你使用浏览器访问所有WWW站点的请求都不会直接发给目的主机,而是先发给代理服务器,代理服务器接受了客户的请求以后,由代理服务器向目的主机发出请求,并接受目的主机的数据,存于代理服务器的硬盘中,然后再由代理服务器将

    2023年04月24日
    浏览(53)
  • 用Java包com.sun.net.httpserver下面的类实现一个简单的http服务器demo

    java的com.sun.net.httpserver包下的类提供了一个高层级的http服务器API,可以用来构建内嵌的http服务器。支持http和https。这些API提供了一个RFC 2616 (HTTP 1.1)和RFC 2818 (HTTP over TLS)的部分实现。 https://docs.oracle.com/en/java/javase/19/docs/api/jdk.httpserver/com/sun/net/httpserver/package-summary.html 下面来实

    2024年02月07日
    浏览(44)
  • .NET Core(C#)使用Titanium.Web.Proxy实现Http(s)代理服务器监控HTTP请求

    关于Titanium.Web.Proxy详细信息可以去这里仔细看看,这里只记录简单用法 NuGet直接获取Titanium.Web.Proxy 配置 与其说是配置,不如就说这一部分就是未来你需要使用的部分,想知道具体每个部分是干什么的就去看原文链接 全放过来太占地方 最后的 Console.Read(); 是一个等待函数,你

    2024年02月09日
    浏览(58)
  • Java 网络编程 —— 创建非阻塞的 HTTP 服务器

    HTTP 客户程序必须先发出一个 HTTP 请求,然后才能接收到来自 HTTP 服器的响应,浏览器就是最常见的 HTTP 客户程序。HTTP 客户程序和 HTTP 服务器分别由不同的软件开发商提供,它们都可以用任意的编程语言编写。HTTP 严格规定了 HTTP 请求和 HTTP 响应的数据格式,只要 HTTP 服务器

    2024年02月06日
    浏览(48)
  • java代码构建简单http服务器和客户端

    初识http a、超文本传输 、应用层的面向对象的协议,概念介绍网上资源一大堆,关键是基于TCP/IP通信协议来传递数据。 b、一开始接触web项目,都是先接触的servlet,tomcat服务器默认实现的一套http规范,提供了基础服务和组件环境,直接拿到请求、构建正文、响应客户端 然而

    2024年02月10日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包