在日常的开发中,我们用过非常多开源的webserver,比如tomcat、apache等等。如今我们自己实现一个简单的webserver,主要的功能就是用户点击要訪问的资源,server将资源发送到client的浏览器。为了简化操作。这里不考虑资源不存在等异常情况。web服务基于的是HTTP协议。用户在浏览器的地址栏输入要訪问的地址,server怎样得到该地址是个关键。先看下一般的HTTP请求和响应报文的一般格式:

HTTP 请求报文

HTTP 响应报文

webserver获取一个用户的连接时,会初始化一个线程和用户通信,代码例如以下:

import java.io.DataInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.PrintStream;

import java.net.Socket;

//每有一个连接建立时,server分出一个通信的线程

public class CommunicateThread extends Thread{

//与客户端通信的套接字

Socket client;

public CommunicateThread(Socket s) {

client = s;

}

//获取浏览器请求资源的路径

public String getResourcePath(String s){

// 一般的HTTP请求报文的第一行是“GET /index.html HTTP/1.1”

// 我们要获取的就是中间的"/indext.apsx"

//获取资源的位置

String s1 = s.substring(s.indexOf(' ')+1);

s1 = s1.substring(1,s1.indexOf(' '));

//默认资源为index.html

if(s1.equals(""))

s1 = "index.html";

return s1;

}

public void sendFile(PrintStream out,File file){

try{

DataInputStream in = new DataInputStream(new FileInputStream(file));

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

byte buf[] = new byte[len];

in.readFully(buf);//读取文内容到buf数组中

out.write(buf,0,len);

out.flush();

in.close();

}

catch(Exception e){

System.out.println(e.getMessage());

System.exit(1);

}

}

public void run(){

try{

//获取用户的IP地址和端口号

String clientIP = client.getInetAddress().toString();

int clientPort = client.getPort();

//创建输出流对象

PrintStream out = new PrintStream(client.getOutputStream());

//创建输入流对象

DataInputStream in = new DataInputStream(client.getInputStream());

//读取浏览器提交的请求

String msg = in.readLine();

//获取文件路径

String fileName = getResourcePath(msg);

System.out.println("The user asked for resource: "+fileName);

File file = new File(fileName);

if(file.exists()){

//依据响应报文格式设置

System.out.println(fileName+" start send");

out.println("HTTP/1.0 200 OK");

out.println("MIME_version:1.0");

out.println("Content_Type:text/html");

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

out.println("Content_Length:"+len);

out.println("");//报文头和信息之间要空一行

//发送文件

sendFile(out,file);

out.flush();

}

client.close();

}

catch(Exception e){

System.out.println(e.getMessage());

}

}

}

server主要负责初始化套接字和线程。代码例如以下:

import java.net.ServerSocket;

import java.net.Socket;

public class WebServer {

public static void main(String[] args) {

int Port = 12345;//端口号,因为这里是測试,所以不要使用经常使用端口

//创建两个套接字

ServerSocket server = null;

Socket client = null;

try{

server = new ServerSocket(Port);

//服务器開始监听

System.out.println("The WebServer is listening on port "+server.getLocalPort());

while(true){

client = server.accept();

//多线程执行

new CommunicateThread(client).start();

}

}catch(Exception e){

System.out.println(e.getMessage());

}

}

}

执行測试:

编写一个index.html文件

This is the index of my WebServer


放到项目文件的根文件夹,然后在浏览器地址栏输入:“localhost:12345/index.html”,就能够看到位于server端的html文件了。注意因为server是死循环,重新启动server会发现指定的port已被绑定,仅仅须要进入任务管理器,关闭"Java(TM) Platfrom SE binary"进程就可以。最后结果例如以下所看到的:

这个server程序非常简陋,还有非常大的改进余地。

大家能够自己尝试改进。这里能够尝试一下訪问其它的文件,发现时成功的。说明这server非常不安全呀。

webserver java_java实现简单webserver(分析+源码)相关推荐

  1. 全网最简单的dubbo源码调试,建议点赞收藏!!!

    dubbo这两年非常的火,那光知道怎么用不行,我这章就告诉你们最简单搭建dubbo源码的方法,记得收藏!! 1.准备环境 IDEA你随便 Maven 3.5.6及以上版本 Dubbo源码版本2.7.3 ...

  2. 简单工厂 jdk源码解析

    我们看一下简单工厂在JDK源码的一些体现,我们看一个比较熟悉的类,Calendar这么一个类,我们找一个getInstance这么一个方法,public static Calendar getInst ...

  3. android 自定义相机源码,Android 自定义相机及分析源码

    Android 自定义相机及分析源码 使用Android 系统相机的方法: 要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下 action的作用就是声明action ...

  4. bytebuddy实现原理分析 源码分析 (三)- advice 详解

    advice详解 八.advice 8.1 AsmVisitorWrapper 8.1.1 ForDeclareFields 8.1.1.1 Entry 8.1.1.2 DispatchingVisi ...

  5. easyloader [easyui_1.4.2] 分析源码,妙手偶得之

    用easyui很久了,但是很少去看源码. 有解决不了的问题就去百度... 今日发现,easyui的源码不难懂. 而且结合 easyloader 可以非常方便的逐个研究easyui的组件. 但是, ea ...

  6. bytebuddy实现原理分析 源码分析 (二)

    bytebuddy实现原理分析 &源码分析 四.字节码的操作(implementation ) pkg 4.1 bytecode :pkg 4.1.1 StackManipulation :c ...

  7. Android自定义底部弹出窗-dialog(2种实现分析+源码)

    Android自定义底部弹出窗-dialog(2种实现分析+源码) 上线项目功能抽取,在项目开发中,我们会在许多地方会用到底部自定义弹窗,比如设置:个人账户退出,切换,照片的拍照或者相册的调出,或者一 ...

  8. python 抓取解析接口数据_[干货]用python抓取摩拜单车API数据并做可视化分析(源码)...

    原标题:[干货]用python抓取摩拜单车API数据并做可视化分析(源码) 在APP中能看到很多单车,但走到那里的时候,才发现车并不在那里.有些车不知道藏到了哪里:有些车或许是在高楼的后面,由于有GP ...

  9. Flink源码分析 - 源码构建

    本篇文章首发于头条号Flink源码分析 - 源码构建,欢迎关注我的头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech)获取更多干货,也欢迎关注我的C ...

  10. SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载

    转载自   SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载 基本准备工作 1.安装JDK1.6以上版本,安装与配置 2.下载mybatis-3.2.0版:htt ...

最新文章

  1. WPF 获取鼠标屏幕位置、窗口位置、控件位置
  2. import javax.servlet.ServletRequest 关于IDEA javax.servlet.http.HttpServletRequest 不存在 解决方案
  3. python是什么牌子主机_python 收集主机信息
  4. [vue] vue给组件绑定自定义事件无效怎么解决?
  5. 高通全系列手机处理器深度解析 (升级选手机必备)附参数对比表
  6. Yum本地Rpm库设置
  7. vmware虚拟化之vswitch详细资料
  8. Linux安装Django
  9. 翻译:Vim从入门到精通 Mac OS
  10. Android是如何绘制View的
  11. java浪曦学习日志 异常类
  12. 给SLAM小车添加 手柄遥控 功能 罗技F710和PS4 手柄
  13. 生产制造行业ERP系统十大品牌
  14. 2019中南大学考研计算机考试,2019年中南大学计算机考研经验分享(复试+真题)...
  15. android studio找不到aar,AndroidStudio 引入aar时常见问题
  16. linux终端显示打印记录,Ubuntu使用-记录终端输出的LOG
  17. 手动搭建高可用的Redis5.0分片集群,从理论到实践,超详细
  18. 城市交通大脑的内涵与顶层设计
  19. DataScience:数据生成之在原始数据上添加小量噪声进而实现构造新数据
  20. Mac OS X Mavericks 迅雷下载地址 ( mac os x 10.9 )

热门文章

  1. OpenStack Queens版本Barbican项目介绍
  2. 【协同任务】基于matlab二阶一致性算法多无人机协同编队动态仿真【含Matlab源码 1740期】
  3. 【优化算法】混合增强灰狼优化布谷鸟搜索算法(AGWOCS)【含Matlab源码 1331期】
  4. 【优化预测】基于matlab布谷鸟算法优化灰色模型预测【含Matlab源码 1244期】
  5. 【优化选址】基于matlab粒子群算法求解充电站规划优化问题【含Matlab源码 664期】
  6. 【纸牌识别】基于matlab灰度二值化纸牌识别【含Matlab源码 464期】
  7. 【图像重建】基于matlab ASTRA算法图像重建【含Matlab源码 090期】
  8. ai替代数据可视化_在药物发现中可视化AI初创公司
  9. python 中 or 的特殊用法,很有用的一个用法
  10. linux 数据转为曲线图,Linux系统下生成TPS,ResponseTime曲线图