本文为原创,如需转载,请注明作者和出处,谢谢!
上一篇:Java网络编程从入门到精通(21):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模拟器在后面的文章中会经常使用,读者可以从本文的开始部分下载Http模拟器的源代码和.class文件。
下一篇:
Java网络编程从入门到精通(23):HTTP消息头字段
国内最棒的Google Android技术社区(eoeandroid),欢迎访问!《银河系列原创教程》发布《Java Web开发速学宝典》出版,欢迎定购
分享到:
相关推荐
0.1《HCL从入门到精通》课程介绍.avi 1.1 HCL模拟器介绍介绍.avi 1.2 HCL安装与调试.avi 1.3 HCL软件界面介绍.avi 1.4 使用HCL创建网络拓扑.avi 1.5 使用Putty登陆并管理设备.avi 1.6 保存并导出HCL项目.avi 1.7 ...
GNS3网络模拟器从入门到精通系列教程,思科网络模拟仿真软件,非常好用的仿真视频学习
JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器JAVA模拟器
《Android从入门到精通》从初学者的角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了Android应用程序开发应该掌握的各方面技术。全书共分15章,内容包括Android快速入门、Android模拟器与常用命令、用户...
《Android移动应用开发从入门到精通》涵盖了Android开发从概念、技术到市场推广应用的全部话题,内容包括:Android概览、Android应用程序设计精髓、Android用户界面设计精髓、常用AndroidAPI、更多Android应用程序...
cmpp2 java实现以及模拟器,cmpp2 java实现以及模拟器,
《Android从入门到精通》从初学者的角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了Android应用程序开发应该掌握的各方面技术。全书共分15章,内容包括Android快速入门、Android模拟器与常用命令、用户...
《Android从入门到精通》从初学者的角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了Android应用程序开发应该掌握的各方面技术。全书共分15章,内容包括Android快速入门、Android模拟器与常用命令、用户...
从0学linux运维 网络篇:思科PT模拟器 我这里使用的是比较老的6版本,已经够了,有兴趣的也可以去网上下载最新版本
《计算机系统结构》清华:DOC+模拟器.7z
Linux操作系统入门书,比较全面 目录 0 前言 0.1 什么是Linux? 0.2 本手册概述 0.3 速查信息 0.4 从以前版本的Red Hat Linux升级 0.5 开发者的话 0.6 编者的话 1 Red Hat Linux 5.1新特性 1.1 安装性能的...
JAVA模拟器
mrp的java模拟器 mrp的java模拟器 mrp的java模拟器 mrp的java模拟器
java模拟器java模拟器java模拟器java模拟器java模拟器
java做的qq模拟器,可实现局域网聊天java做的qq模拟器,可实现局域网聊天
MSS:船舶系统模拟器(MSS)
《Android移动应用开发从入门到精通》涵盖了Android开发从概念、技术到市场推广应用的全部话题,内容包括:Android概览、Android应用程序设计精髓、Android用户界面设计精髓、常用AndroidAPI、更多Android应用程序...
JAVA模拟器.rar
《Android从入门到精通》 第1章 初识Android 1.1 什么是Android 1.1.1 移动信息设备分类 1.1.2 Open Handset Alliance和 Android 1.2 Android简介 1.2.1 Andriod的历史 1.2.2 Andriod的未来 1.2.3 Andriod平台的技术...
java 模拟器 ningyunyoulong