`
haierboos
  • 浏览: 439146 次
文章分类
社区版块
存档分类
最新评论

Java网络编程:实现HTTP模拟器

 
阅读更多

本文为原创,如需转载,请注明作者和出处,谢谢!

源代码和.class文件下载

在讨论HTTP协议的具体请求和响应头字段之前,让我们先来利用以前所学的知识来实现一个HTTP模拟器。所谓HTTP模拟器就是可以在用户输入HTTP 的请求消息后,由这个模拟器将HTTP请求发送给相应的服务器,再接收服务器的响应消息。这个HTTP模拟器有几下特点:

1. 可以手工输入HTTP请求,并向服务器发送。

2. 接收服务器的响应消息。

3. 消息头和实体内容分段显示,也就是说,并不是象Telnet等客户端一样将HTTP响

应消息全部显示,而是先显示消息头,然后由用户决定是否显示实体内容。

4. 集中发送请求。这个HTTP模拟器和Telnet不同的是,并不是一开始就连接服务器,

而是将域名、端口以及HTTP请求消息都输完后,才连接服务器,并将这些请求发送给服务器。这样做的可以预防服务器提前关闭网络连接的现象。

5. 可以循环做上述的操作。

从以上的描述看,要实现这个HTTP模拟器需要以下五步:

1. 建立一个大循环,在循环内部是一个请求/响应对。这样就可以向服务器发送多次请求/响应以了。下面的四步都是被包括在循环内部的。

2. 从控制台读取域名和端口,这个功能可以由readHostAndPort(...)来完成。

3. 从控制台读取HTTP请求消息,这个功能由readHttpRequest(...)来完成。

4. 向服务器发送HTTP请求消息,这个功能由sendHttpRequest()来完成。

5. 读取服务器回送的HTTP响应消息,这个功能由readHttpResponse(...)来完成。

下面我们就来逐步实现这五步:

一、建立一个大循环

在建立这个循环之前,先建立一个中叫HttpSimulator的类,并在这个类中定义一个run方法用来运行这个程序。实现代码如下:

001package http;
002
003importjava.net.*;
004importjava.io.*;
005
006publicclassHttpSimulator
007{
008privateSocketsocket;
009privateintport=80;
010privateStringhost="localhost";
011privateStringrequest="";//HTTP请求消息
012privatebooleanisPost,isHead;
013
014publicvoidrun()throwsException
015{
016BufferedReaderreader=newBufferedReader(newInputStreamReader(
017System.in));
018while(true)//开始大循环
019{
020try
021{
022if(!readHostAndPort(reader))
023break;
024readHttpRequest(reader);
025sendHttpRequest();
026readHttpResponse(reader);
027}
028catch(Exceptione)
029{
030System.out.println("err:"+e.getMessage());
031}
032}
033}
034publicstaticvoidmain(String[]args)throwsException
035{
036newHttpSimulator().run();
037}
038}

从上面的代码可以看出, 第022、024、025和026分别调用了上述的四个方法。这些方法的具体实现将在后面讨论。上面的代码除了调用这四个核心方法外,还做了一些准备工 作。在008至012行定义了一些以后要用到的变量。在016和017行使用控制台的输入流建立了BufferedReader对象,通过这个对象,可以 直接从控制台读取字符串,而不是一个个地字节。

二、readHostAndPort(...)
方法的实现

这个方法的主要功能是从控制台读取域名和端口。域名和端口通过":"隔开,":"和域名以及端口之间不能有空格。当从控制台读取一个"q"时,这个函数返回false,表示程序可以退出了,否则返回true,表示输入的域名和端口是正确的。这个方法的实现代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->001privatebooleanreadHostAndPort(BufferedReaderconsoleReader)
002throwsException
003{
004System.out.print("host:port>");
005String[]ss=null;
006Strings=consoleReader.readLine();
007if(s.equals("q"))
008returnfalse;
009else
010{
011ss=s.split("[:]");
012if(!ss[0].equals(""))
013host=ss[0];
014if(ss.length>1)
015port=Integer.parseInt(ss[1]);
016System.out.println(host+":"+String.valueOf(port));
017returntrue;
018}
019}

第001行:这个方法有一个BufferedReader类型的参数,这个参数的值就是在HttpSimulator.java中的第016和017行根据控制台输入流建立的BufferedReader对象。

第 004 行:这输出HTTP模拟器的控制符,就象Windows的控制台的"C:">"一样。

第 006 行:从控制台读取一行字符串。

第 011 行:通过字符串的split方法和响应的正则表示式("[:]")将域名和端口分开。域名的默认值是localhost,端口的默认值是80。

三、readHttpRequest(...)
方法的实现

这个方法的主要功能是从控制台读取HTTP请求消息,如果输入一个空行,表示请求消息头已经输完;如果使用的是POST方法,还要输入POST请求的实体内容。这个方法的实现代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->001privatevoidreadHttpRequest(BufferedReaderconsoleReader)
002throwsException
003{
004System.out.println("请输入HTTP请求:");
005Strings=consoleReader.readLine();
006request=s+"/r/n";
007booleanisPost=s.substring(0,4).equals("POST");
008booleanisHead=s.substring(0,4).equals("HEAD");
009while(!(s=consoleReader.readLine()).equals(""))
010request=request+s+"/r/n";
011request=request+"/r/n";
012if(isPost)
013{
014System.out.println("请输入POST方法的内容:");
015s=consoleReader.readLine();
016request=request+s;
017}
018}

第 005 行:读入HTTP请求消息的第一行。

第 007、008行:确定所输入的请求方法是不是POST和HEAD。

第 009、010行:读入HTTP请求消息的其余行。

第012 ? 017行:如果HTTP请求使用的是POST方法,要求用户继续输入HTTP请求的实体内容。

四、sendHttpRequest()
方法的实现

这个方法的功能是将request变量中的HTTP请求消息发送到服务器。下面是这个方法的实现代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->001privatevoidsendHttpRequest()throwsException
002{
003socket=newSocket();
004socket.setSoTimeout(10*1000);
005System.out.println("正在连接服务器");
006socket.connect(newInetSocketAddress(host,port),10*1000);
007System.out.println("服务器连接成功!");
008OutputStreamout=socket.getOutputStream();
009OutputStreamWriterwriter=newOutputStreamWriter(out);
010writer.write(request);
011writer.flush();
012}

第004行:设置读取数据超时为10秒。

第006行:连接服务器,并设置连接超时为10秒。

五、readHttpResponse(...)
方法的实现

这个方法的主要功能是从服务器读取返回的响应消息。首先读取了响应消息头,然后要求用户输入Y或N以确定是否显示响应消息的实体内容。这个程序之所以这样做,主要有两个原因:

(1) 为了研究HTTP协议。

(2) 由于本程序是以字符串形式显示响应消息的,因此,如果用户请求了一个二进制Web资源,如一个rar文件,那么实体内容将会显示乱码。所以在显示完响应消息头后由用户决定是否显示实体内容。

这个方法的实现代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->001privatevoidreadHttpResponse(BufferedReaderconsoleReader)
002{
003Strings="";
004try
005{
006InputStreamin=socket.getInputStream();
007InputStreamReaderinReader=newInputStreamReader(in);
008BufferedReadersocketReader=newBufferedReader(inReader);
009System.out.println("---------HTTP头---------");
010booleanb=true;//true:未读取消息头false:已经读取消息头
011while((s=socketReader.readLine())!=null)
012{
013if(s.equals("")&&b==true&&!isHead)
014{
015System.out.println("------------------------");
016b=false;
017System.out.print("是否显示HTTP的内容(Y/N):");
018Stringchoice=consoleReader.readLine();
019if(choice.equals("Y")||choice.equals("y"))
020{
021System.out.println("---------HTTP内容---------");
022continue;
023}
024else
025break;
026}
027else
028System.out.println(s);
029}
030}
031catch(Exceptione)
032{
033System.out.println("err:"+e.getMessage());
034}
035finally
036{
037try
038{
039socket.close();
040}
041catch(Exceptione)
042{
043}
044}
045System.out.println("------------------------");
046}

在上面的代码中013行 是最值得注意的。其中s.equals("")表示读入一个空行(表明消息头已经结束);由于在实体内容中也可以存在空行,因此,b == true来标记消息头是否已经被读过,当读完消息头后,将b设为false,如果以后再遇到空行,就不会当成消息头来处理了。当HTTP请求使用HEAD 方法时,服务器只返回响应消息头;因此,使用!isHead来保证使用HEAD发送请求时不显示响应消息的内容实体。

现在我们已经实现了这个HTTP模拟器,下面让我们来运行并测试它。

运行

运行如下的命令

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->javahttp.HttpSimulator

运行以上的命令后,将显示如图1所示的界面。

图1

测试

在HTTP模拟器中输入如下的域名:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->www.csdn.net

在HTTP模拟器中输入如下的HTTP请求消息:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->GET/HTTP/1.1
Host:www.csdn.net

运行的结果如图2所示。

图2

读者可以从本文的开始部分下载Http模拟器的源代码和.class文件。

分享到:
评论

相关推荐

    CacheSimulator:Java缓存模拟器

    Java缓存模拟器 ##它是什么? 面向对象编程和设计 (Java) 课程的学校项目。 我们给出了一个示例 GUI 和一个程序规范。 该作业不是小组项目,而是在 2 周的时间内单独完成。 ##程序架构 显然,由于这是面向对象...

    java网络编程采用TCP实现模拟服务器

    学生期末课程大作业,java高级网络编程中TCP实现多用户模拟器。源码!!!

    Network-Simulator:IME-USP 计算机网络编程课程的网络模拟器

    网络模拟 IME-USP 计算机网络编程课程的网络模拟器。

    帮助初学者学习FTCRoboticsJava编程的2D机器人模拟器_Java_下载.zip

    帮助初学者学习FTCRoboticsJava编程的2D机器人模拟器_Java_下载.zip

    Java-Projekt-PO:古代帝国模拟器

    这是一个最终项目,作为对象编程主题的一部分实施。 该项目应该在 NetBeans 7.3.1 或更新的环境中打开。 注:一开始,地图上创建了27个商人。 第一个野蛮人将在 40 秒后出现,但不会早于 10 秒。 首都将被最后攻击...

    CoffeeMachine:咖啡机模拟器。 该项目来自Hyperskill.io,该项目以3种不同的方式完成,最终的源代码更加简洁-java project source code

    尝试使用循环和条件,对Java编程更有信心。 第一阶段:你好,咖啡! 编写一个在屏幕上显示基本信息的程序:让机器有机会告诉客户它在做什么! 描述: 让我们从一个为您提供咖啡的程序开始-当然是虚拟咖啡。 ...

    java-gb:用Java编写的正在进行中的GameBoy模拟器

    java-gb文件 Gameboy指令集: : Gameboy操作码摘要: : Gameboy手册(充满错误): : 任天堂Gameboy官方编程手册: : 进展: 产品特点状态笔记 :crossed_swords: 精灵 :check_mark: :joystick: 游戏手柄 :check_...

    strangefx:量子计算机模拟器

    特效 StrangeFX是基于Java(FX)的Quantum计算机视觉编辑器。 它利用了项目导出的Quantum计算机模拟器软件。 看看Strange可以开始使用这些概念。 利用Strange和StrangeFX可视化以编程方式创建的电路。 StrangeFX还...

    Transfermarkt_Simulator-JDBC:项目Transfermarkt模拟器。 使用JDBC

    项目Transfermarkt模拟器。 使用JDBC。 这是通过控制台实现的Transfermarkt Simulator App。 它与包含有关足球俱乐部,其球员和教练的信息的数据库连接。 因此,编程的思想是允许用户使用此数据进行操作。 例如,...

    Jass:Jass 游戏模拟器,具有可编程 AI,专供 CS1 学生使用

    贾斯Jass 游戏模拟器,具有可编程 AI,专为 CS1 学生设计。 Pre-alpha 版本,该项目正在搬迁中。 如果您仍然需要预览,请运行old.Test.java或gui.Main.java 。

    GNES_JAVA:使用LibGDX用Java编程的WIP NES模拟器

    围绕用Java创建的WIP NES模拟器。 有点凌乱,并没有做很多事情。 支持NROM,MMC1(部分),MMC3(部分),UxROM和GxROM映射器。 主要是为了娱乐和学习。 执照 GNES是根据GPLv3许可的。 Copyright (C) 2016 ...

    JAVA运算符号笔试题-recc:编译器、模拟器和微内核工具的集合

    JAVA不同号笔试题2020 年 1 月 24 日更新 在这一点上,我必须承认失败并承认我已经没有时间和金钱来致力于这个项目。 我一直在做咨询/合同工作,这些工作确实显示出一些提供增长和更多资源的承诺,我可以将这些资源...

    JAVA上百实例源码以及开源项目源代码

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    Android C++高级编程:使用NDK_Onur Cinar, 于红PDF电子书下载 带书签目录 完整版

    Android C++高级编程:使用NDK_Onur Cinar, 于红PDF电子书下载 带书签目录 完整版 原书名:Pro Android C++ with the NDK 原出版社: Apress 作者: (美)Onur Cinar 译者: 于红 佘建伟 冯艳红 丛书名: 移动开发...

    java图形界面源码-Jupiter:RISC-V汇编器和运行时模拟器

    java图形界面源码 Jupiter是一个开源且面向教育的 RISC-V 汇编器和运行时模拟器。 它是用 Java 编写的,能够模拟基本整数 ISA( I扩展)加上M和F扩展( RV32IMF )的所有指令,包括用户级指令集手册1 中描述的所有伪...

    SQSim:简单队列模拟器-开源

    该应用程序对具有简单概率队列动态性的系统建模很有用。... 是在NetBeans IDE下用Java编程的应用程序。 项目制作人:哥伦比亚国立大学的Oscar JavierCortésArrigui工业工程系学生ojcortesa@unal.edu.co

    JAVA上百实例源码以及开源项目

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    java开源包4

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    MIPS:MIPS模拟器

    使用的编程语言是JAVA。 我们为所有包含控制信号的指令创建了一个超类(每条指令都有自己的控制信号)。 该类具有三个子类:R 格式、I 格式和 J 格式。 这三个中的每一个都包含其独特的属性。 应支持的所有指令都是...

    java开源包3

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

Global site tag (gtag.js) - Google Analytics