网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  如何用java实现web服务器     
  文章作者:未知  文章来源:水木森林  
  查看:56次  录入:管理员--2007-11-17  
 

    一、http协议的作用原理

    www是以internet作为传输媒介的一个应用系统,www网上最基本的传输单位是web网页。www的工作基于客户机/服务器计算模型,由web 浏览器(客户机)和web服务器(服务器)构成,两者之间采用超文本传送协议(http)进行通信。http协议是基于tcp/ip协议之上的协议,是web浏览器和web服务器之间的应用层协议,是通用的、无状态的、面向对象的协议。http协议的作用原理包括四个步骤:

    (1) 连接:web浏览器与web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接建立成功。

    (2) 请求:web浏览器通过socket向web服务器提交请求。http的请求一般是get或post命令(post用于form参数的传递)。get命令的格式为:

    get 路径/文件名 http/1.0

    文件名指出所访问的文件,http/1.0指出web浏览器使用的http版本。

    (3) 应答:web浏览器提交请求后,通过http协议传送给web服务器。web服务器接到后,进行事务处理,处理结果又通过http传回给web浏览器,从而在web浏览器上显示出所请求的页面。

    例:假设客户机与www.mycompany.com:8080/mydir/index.html建立了连接,就会发送get命令:get /mydir/index.html http/1.0.主机名为www.mycompany.com的web服务器从它的文档空间中搜索子目录mydir的文件index.html.如果找到该文件,web服务器把该文件内容传送给相应的web浏览器。

    为了告知 web浏览器传送内容的类型,web服务器首先传送一些http头信息,然后传送具体内容(即http体信息),http头信息和http体信息之间用一个空行分开。

    常用的http头信息有:

    ① http 1.0 200 ok

    这是web服务器应答的第一行,列出服务器正在运行的http版本号和应答代码。代码“200 ok”表示请求完成。

    ② mime_version:1.0

    它指示mime类型的版本。

    ③ content_type:类型

    这个头信息非常重要,它指示http体信息的mime类型。如:content_type:text/html指示传送的数据是html文档。

    ④ content_length:长度值

    它指示http体信息的长度(字节)。

    (4) 关闭连接:当应答结束后,web浏览器与web服务器必须断开,以保证其它web浏览器能够与web服务器建立连接。

    二、java实现web服务器功能的程序设计

    根据上述http协议的作用原理,实现get请求的web服务器程序的方法如下:

    (1) 创建serversocket类对象,监听端口8080.这是为了区别于http的标准tcp/ip端口80而取的;

    (2) 等待、接受客户机连接到端口8080,得到与客户机连接的socket;

    (3) 创建与socket字相关联的输入流instream和输出流outstream;

    (4) 从与socket关联的输入流instream中读取一行客户机提交的请求信息,请求信息的格式为:get 路径/文件名 http/1.0

    (5) 从请求信息中获取请求类型。如果请求类型是get,则从请求信息中获取所访问的html文件名。没有html文件名时,则以index.html作为文件名;

    (6) 如果html文件存在,则打开html文件,把http头信息和html文件内容通过socket传回给web浏览器,然后关闭文件。否则发送错误信息给web浏览器;

    (7) 关闭与相应web浏览器连接的socket字。

    下面的程序是根据上述方法编写的、可实现多线程的web服务器,以保证多个客户机能同时与该web服务器连接。

    程序1:webserver.java文件

    //webserver.java 用java编写web服务器

    import java.io.*;

    import java.net.*;

    public class webserver {

    public static void main(string args[]) {

    int i=1, port=8080;

    serversocket server=null;

    socket client=null;

    try {

    server=new serversocket(port);

    system.out.println("web server is listening on port "+server.getlocalport());

    for (;;) {client=server.accept(); //接受客户机的连接请求

    new connectionthread(client,i)。start();

    i++;

    }

    } catch (exception e) {system.out.println(e);}

    }

    }

    /* connnectionthread类完成与一个web浏览器的通信 */

    class connectionthread extends thread {

    socket client; //连接web浏览器的socket字

    int counter; //计数器

    public connectionthread(socket cl,int c) {

    client=cl;

    counter=c;

    }

    public void run() //线程体

    {try {

    string destip=client.getinetaddress()。tostring(); //客户机ip地址

    int destport=client.getport(); //客户机端口号

    system.out.println("connection "+counter+":connected to "+destip+" on port "+destport+".");

    printstream outstream=new printstream(client.getoutputstream());

    datainputstream instream=new datainputstream(client.getinputstream());

    string inline=instream.readline(); //读取web浏览器提交的请求信息

    system.out.println("received:"+inline);

    if (getrequest(inline)) { //如果是get请求

    string filename=getfilename(inline);

    file file=new file(filename);

    if (file.exists()) { //若文件存在,则将文件送给web浏览器

    system.out.println(filename+" requested.");

    outstream.println("http/1.0 200 ok");

    outstream.println("mime_version:1.0");

    outstream.println("content_type:text/html");

    int len=(int)file.length();

    outstream.println("content_length:"+len);

    outstream.println("");

    sendfile(outstream,file); //发送文件

    outstream.flush();

    } else { //文件不存在时

    string notfound="

   

error 404-file not found

";

    outstream.println("http/1.0 404 no found");

    outstream.println("content_type:text/html");

    outstream.println("content_length:"+notfound.length()+2);

    outstream.println("");

    outstream.println(notfound);

    outstream.flush();

    }

    }


    long m1=1;

    while (m1<11100000) {m1++;} //延时

    client.close();

    } catch (ioexception e) {

    system.out.println("exception:"+e);

    }

    }

    /* 获取请求类型是否为“get” */

    boolean getrequest(string s) {

    if (s.length()>0)

    {if (s.substring(0,3)。equalsignorecase("get")) return true;

    }

    return false;

    }

    /* 获取要访问的文件名 */

    string getfilename(string s) {

    string f=s.substring(s.indexof(′ ′)+1);

    f=f.substring(0,f.indexof(′ ′));

    try {

    if (f.charat(0)==′/′)

    f=f.substring(1);

    } catch (stringindexoutofboundsexception e) {

    system.out.println("exception:"+e);

    }

    if (f.equals("")) f="index.html";

    return f;

    }

    /*把指定文件发送给web浏览器 */

    void sendfile(printstream outs,file file) {

    try {

    datainputstream in=new datainputstream(new fileinputstream(file));

    int len=(int)file.length();

    byte buf[]=new byte[len];

    in.readfully(buf);

    outs.write(buf,0,len);

    outs.flush();

    in.close();

    } catch (exception e) {

    system.out.println("error retrieving file.");

    system.exit(1);

    }

    }

    }

    程序中的connectionthread线程子类用来分析一个web浏览器提交的请求,并将应答信息传回给web浏览器。其中,getrequest()方法用来检测客户的请求是否为“get”;getfilename(s)方法是从客户请求信息s中获取要访问的html文件名;sendfile()方法把指定文件内容通过socket传回给web浏览器。

    对上述程序的getrequest()方法和相关部分作修改,也能对post请求进行处理。

    三、运行实例

    为了测试上述程序的正确性,将编译后的webserver.class、connectionthread.class和下面的index.html文件置于网络的某台主机的同一目录中(如:主机nt40srv的c:jweb目录)。

    程序2:index.html文件

   

   

   

   

   

   

   

这是用java写出的web服务器主页

    1998年8月28日

   


   

   

    首先在该主机上用java命令运行webserver.class:

    c:jweb>java webserver

    然后在客户机运行浏览器软件,在url处输入webserver程序所属的url地址(如:http://nt40srv:8080/index.html),就在浏览器窗口显示出指定的html文档。

    注意,不能缺省端口号8080,如缺省,则运行该主机的正常web服务器。

    说明,不具备网络条件的可在安装了windows 95的单机上进行测试,方法是用localhost或127.0.0.1代替url地址的域名部分,即url地址为http://localhost:8080.

 
 
上一篇: ant十五大最佳实践经典案例分析    下一篇: eclipse插件的外挂安装方法
  相关文档
java入门教程:数据类型 11-17
j2ee中几种业务代理模式的实现和比较 11-16
技术分析:使用eclipse进行swt编程(图) 11-17
j2ee基础:怎样读取和处理xml的配置文件 11-16
java中sprite类的definereferencepixel(x,y) 11-17
树形结构的实现 11-17
简析java的xml编程 11-17
java笔记 11-17
使用digester解析xml文档示例 11-17
java中文乱码解决方案和经验 11-17
sun mustang 进入2006 11-17
关于java的classpath详解 11-16
java初学者实践教程27-applet 11-20
一个计时类 11-16
java新手必备:java基础之关键字 11-16
java 中protected modifier 使用总结 11-17
可扩展的java应用程序开发模式 11-16
浅析java语言中两种异常在使用时的差别 11-16
对spring中接口注入的理解实例分析 11-17
如何在java中实现jobscheduling 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息