前往顾页
以后地位: 主页 > 收集编程 > Jsp实例教程 >

java版简略单纯HTTP办事器代码

时候:2012-02-25 15:09来源:知行网www.zhixing123.cn 编辑:麦田守望者

import java.io.*;
import java.net.*;
import java.util.StringTokenizer;

/**
* 一个简朴的用 Java Socket 编写的 HTTP 办事器利用, 演示了要乞降应答的和谈通信内容和
* 给客户端前往 HTML 文本和二进制数据文件(一个图片), 同时揭示了 404, 200 等状况码.
* 起首运行这个法度,然后翻开Web浏览器,键入http://localhost,则这个法度可以或许显现出浏览器发送了那些信息
* 并且向浏览器前往一个网页和一副图片, 并测试同浏览器对话.
* 当浏览器看到 HTML 中带有图片地点时, 则会发出第二次连接来请求图片等资本.
* 这个例子可以帮您了解 Java 的 HTTP 办事器软件是基于 J2SE 的 Socket 等软件编写的观点, 并熟谙
* HTTP和谈.
* 相反的用 Telnet 连接到已有的办事器则可以帮手了解浏览器的运行过程和办事器端的前往内容.
*
* <pre>
* 当用户在Web浏览器地点栏中输入一个带有http://前缀的URL并按下Enter后,或在Web页面中某个以http://开首的超链接上单击鼠标,HTTP事件措置的第一个阶段–建立连接阶段就开端了.HTTP的默许端口是80.
* 跟着连接的建立,HTTP就进入了客户向办事器发送请求的阶段.客户向办事器发送的请求是一个有特定格局的ASCII动静,其语法规则为:
* < Method > < URL > < HTTP Version > <\n>
* { <Header>:<Value> <\n>}*
* <\n>
* { Entity Body }
* 请求动静的顶端是请求行,用于指定体例,URL和HTTP和谈的版本,请求行的最后是回车换行.体例有GET,POST,HEAD,PUT,DELETE等.
* 在请求行以后是多少个报头(Header)行.每个报头行都是由一个报头和一个取值构成的二元对,报头和取值之间以":"分开;报头行的最后是回车换行.常见的报头有Accept(指定MIME媒体范例),Accept_Charset(呼应动静的编码体例),Accept_Encoding(呼应动静的字符集),User_Agent(用户的浏览器信息)等.
* 在请求动静的报头行以后是一个回车换行,表白请求动静的报头部分结束.在这个\n以后是请求动静的动静实体(Entity Body).详细的例子参看httpRequest.txt.
* Web办事器在收到客户请求并作出措置以后,要向客户发送应答动静.与请求动静一样,应答动静的语法规则为:
* < HTTP Version> <Status Code> [<Message>]<\n>
* { <Header>:<Value> <\n> } *
* <\n>
* { Entity Body }
* 应答动静的第一行动状况行,此中包含了HTTP版本号,状况码和对状况码进行冗长解释的动静;状况行的最后是回车换行.状况码由3位数字构成,有5类:
* 参看:HTTP应答码及其意义
*
* 1XX 保存
* 2XX 表示成功
* 3XX 表示URL已被移走
* 4XX 表示客户错误
* 5XX 表示办事器错误
* 比方:415,表示不支撑改媒体范例;503,表示办事器不克不及拜候.最多见的是200,表示成功.常见的报头有:Last_Modified(最后点窜时候),Content_Type(动静内容的MIME范例),Content_Length(内容长度)等.
* 在报头行以后也是一个回车换行,用以表示应答动静的报头部分的结束,和应答动静实体的开端.
* 下面是一个应答动静的例子:
* HTTP/1.0 200 OK
* Date: Moday,07-Apr-97 21:13:02 GMT
* Server:NCSA/1.1
* MIME_Version:1.0
* Content_Type:text/html
* Last_Modified:Thu Dec 5 09:28:01 1996
* Coentent_Length:3107
*
* <HTML><HEAD><TITLE></HTML>
*
* 在用Java说话实现HTTP办事器时,起首启动一个java.net.ServerSocket在办事器的端口上监听连接.向客户前往文本时,可以用 PrintWriter,但是如果前往二进制数据,则必须利用OutputStream.write(byte[])体例,前往的应答动静字符串可利用 String.getBytes()体例转换为字节数组前往,或利用PrintStream的print()体例写入文本,用 write(byte[])体例写入二进制数据.
*
* </pre>
* @author 刘长炯
* @version 1.0 2007-07-24 Sunday
* @version 1.1 2008-05-18 Sunday
* 支撑浏览器发出的POST信息打印,修改POST体例无法完成呼应造成阻赛的BUG
*/
public class SimpleHttpServer implements Runnable {
/**
*
*/
ServerSocket serverSocket;//办事器Socket

/**
* 办事器监听端口, 默许为 80.
*/
public static int PORT=80;//标准HTTP端口

/**
* 开端办事器 Socket 线程.
*/
public SimpleHttpServer() {
try {
serverSocket=new ServerSocket(PORT);
} catch(Exception e) {
System.out.println("无法启动HTTP办事器:"+e.getLocalizedMessage());
}
if(serverSocket==null) System.exit(1);//无法开端办事器
new Thread(this).start();
System.out.println("HTTP办事器正在运行,端口:"+PORT);
}

/**
* 运行办事器主线程, 监听客户端请求并前往呼应.
*/
public void run() {
while(true) {
try {
Socket client=null;//客户Socket
int contentLength = 0;// 客户端发送的 HTTP 请求的主体的长度
client=serverSocket.accept();//客户机(这里是 IE 等浏览器)已连接到以后办事器
if(client!=null) {
System.out.println("连接到办事器的用户:"+client);
try {
// 第一阶段: 翻开输入流
BufferedReader in=new BufferedReader(new InputStreamReader(
client.getInputStream()));

System.out.println("客户端发送的请求信息:\n===================");
// 读取第一行, 请求地点
String line=in.readLine();
System.out.println(line);
String resource=line.substring(line.indexOf(‘/’),line.lastIndexOf(‘/’)-5);
//获得请求的资本的地点
resource=URLDecoder.decode(resource, "UTF-8");//反编码 URL 地点
String method = new StringTokenizer(line).nextElement().toString();// 获得请求体例, GET 或 POST

// 读取所有浏览器发送过去的请求参数头部信息
while( (line = in.readLine()) != null) {
System.out.println(line);

// 读取 POST 等数据的内容长度
if(line.startsWith("Content-Length")) {
try {
contentLength = Integer.parseInt(line.substring(line.indexOf(‘:’) + 1).trim());
} catch (Exception e) {
e.printStackTrace();
}
}

if(line.equals("")) break;
}

// 显现 POST 表单提交的内容, 这个内容位于请求的主体部分
if("POST".equalsIgnoreCase(method) && contentLength > 0) {
System.out.println("以下内容为 POST 体例提交的表双数据");
for(int i = 0; i < contentLength; i++) {
System.out.print((char)in.read());
}

System.out.println();
}

System.out.println("请求信息结束\n===================");
System.out.println("用户请求的资本是:"+resource);
System.out.println("请求的范例是: " + method);

// GIF 图片就读取一个实在的图片数据并前往给客户端
if(resource.endsWith(".gif")) {
fileService("images/test.gif", client);
closeSocket(client);
continue;
}

// 请求 JPG 格局就报错 404
if(resource.endsWith(".jpg")) {
PrintWriter out=new PrintWriter(client.getOutputStream(),true);
out.println("HTTP/1.0 404 Not found");//前往应答动静,并结束应答
out.println();// 按照 HTTP 和谈, 空即将结束头信息
out.close();
closeSocket(client);
continue;
} else {
// 用 writer 对客户端 socket 输入一段 HTML 代码
PrintWriter out=new PrintWriter(client.getOutputStream(),true);
out.println("HTTP/1.0 200 OK");//前往应答动静,并结束应答
out.println("Content-Type:text/html;charset=GBK");
out.println();// 按照 HTTP 和谈, 空即将结束头信息

out.println("<h1> Hello Http Server</h1>");
out.println("你好, 这是一个 Java HTTP 办事器 demo 利用.<br>");
out.println("您请求的途径是: " + resource + "<br>");
out.println("这是一个支撑假造途径的图片:<img src=’abc.gif’><br>" +
"<a href=’abc.gif’>点击翻开abc.gif, 是个办事器假造途径的图片文件.</a>");
out.println("<br>这是个会反应 404 错误的的图片:<img src=’test.jpg’><br><a href=’test.jpg’>点击翻开test.jpg</a><br>");
out.println("<form method=post action=’/'> <input name=username value=’用户’> <input name=submit type=submit value=submit ></form>");

顶一下
(0)
0%
踩一下
(0)
0%
------分开线----------------------------
标签(Tag):Java JAVA实例教程 JAVA根本教程 Java源代码 Java技能
------分开线----------------------------
颁发评论
请自发遵循互联网相关的政策法规,严禁公布色情、暴力、革命的谈吐。
评价:
神色:
考证码:点击我更换图片
猜你感兴趣