import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 用Java语言实现HTTP服务器,首先启动一个java.net.ServerSocket在提供服务的端口上监听连接.向客户返回文本时,可以用
* PrintWriter,但是如果返回二进制数据,则必须使用OutputStream.write(byte[])方法,返回的应答消息字符串可以使用
* String.getBytes()方法转换为字节数组返回,或者使用PrintStream的print()方法写入文本,用
* write(byte[])方法写入二进制数据.
*
* 以工程所在目录为web的根目录。 在工程的根目录下放一个大概如下的index.html
*
* <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
* "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta
* http-equiv="Content-Type" content="text/html; charset=gbk">
* <title>简单的测试</title> </head> <body> 你好!这是一个 简单的web服务器。<br>
* 这是一个图片!<br>
*
* <form action="/index.html"> <img alt="" src="images/test.gif"><br>
* 姓名:<input type="text" name="name" /><br>
* 密码:<input type="password" name="pass"></input><br>
* <input type="submit"/> </form> </body> </html>
*
* 放入图片位置: 工程根目录/images/test.gif <br>
* 打开浏览器输入http://localhost/index.html 可以展示index.html
*
* @author rommel1
*/
public class SimpleHttpServer {
ServerSocket serverSocket;// 服务器Socket
ExecutorService pool = Executors.newFixedThreadPool(2);
/**
* 服务器监听端口, 默认为 80.
*/
public static int PORT = 80;// 标准HTTP端口
/**
* 开始服务器 Socket 线程.
*/
public SimpleHttpServer() {
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
System.out.println("无法启动HTTP服务器:" + e.getMessage());
}
if (serverSocket == null)
System.exit(1);// 无法开始服务器
// new Thread(this).start();
System.out.println("HTTP服务器正在运行,端口:" + PORT);
while (true) {
pool.execute(new Process(serverSocket));
}
}
/**
* 运行服务器主线程, 监听客户端请求并返回响应.
*/
/** */
/**
* 启动 HTTP 服务器
*
* @param args
*/
public static void main(String[] args) {
try {
if (args.length != 1) {
System.out.println("这是一个简单的web服务器 ,端口是: 80.");
} else if (args.length == 1) {
PORT = Integer.parseInt(args[0]);
}
} catch (Exception ex) {
System.err.println("服务器初始化错误" + ex.getMessage());
}
new SimpleHttpServer();
}
}
class Process extends Thread {
private ServerSocket serverSocket;// 服务器Socket
Process(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
public void run() {
try {
Socket client = null;// 客户Socket
client = serverSocket.accept();// 客户机(这里是 IE 等浏览器)已经连接到当前服务器
if (client != null) {
System.out.println("连接到服务器的用户:" + client);
try {
// 第一阶段: 打开输入流
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
System.out.println("客户端发送的请求信息: ***************");
// 读取第一行, 请求地址
System.out.println("http协议头部信息:");
String line = in.readLine();
System.out.println(line);
String resource = line.substring(line.indexOf('/'),
line.lastIndexOf('/') - 5);
// 获得请求的资源的地址
resource = URLDecoder.decode(resource, "gbk");// 反编码
String method = new StringTokenizer(line).nextElement()
.toString();// 获取请求方法, GET 或者 POST
// 读取浏览器发送过来的请求参数头部信息
while ((line = in.readLine()) != null) {
System.out.println(line);
if (line.equals(""))
break;
}
System.out.println("http协议头部结束 ***************");
System.out.println("用户请求的资源是:" + resource);
System.out.println("请求的类型是: " + method);
String params = null;
if (resource.indexOf("?") > -1) {
params = resource.substring(resource.indexOf("?") + 1);
resource = resource.substring(0, resource.indexOf("?"));
}
// 显示 POST 表单提交的内容, 这个内容位于请求的主体部分
if ("POST".equalsIgnoreCase(method)) {
if (params != null) {
params += "&" + in.readLine();
} else {
params = in.readLine();
}
}
System.out.println("打印提交的数据:");
printParams(params);
// 读取资源并返回给客户端
fileReaderAndReturn(resource, client);
// 关闭客户端链接
client.close();
System.out.println("客户端返回完成!");
} catch (Exception e) {
System.out.println("HTTP服务器错误:" + e.getMessage());
}
}
} catch (Exception e) {
System.out.println("HTTP服务器错误:" + e.getMessage());
}
}
/**
* 读取一个文件的内容并返回给浏览器端.
*
* @param fileName
* 文件名
* @param socket
* 客户端 socket.
* @throws IOException
*/
void fileReaderAndReturn(String fileName, Socket socket) throws IOException {
if ("/".equals(fileName)) {// 设置欢迎页面,呵呵!
fileName = "/index.html";
}
fileName = fileName.substring(1);
PrintStream out = new PrintStream(socket.getOutputStream(), true);
File fileToSend = new File(fileName);
String fileEx = fileName.substring(fileName.indexOf(".") + 1);
String contentType = null;
// 设置返回的内容类型
// 此处的类型与tomcat/conf/web.xml中配置的mime-mapping类型是一致的。测试之用,就写这么几个。
if ("htmlhtmxml".indexOf(fileEx) > -1) {
contentType = "text/html;charset=GBK";
} else if ("jpegjpggifbpmpng".indexOf(fileEx) > -1) {
contentType = "application/binary";
}
if (fileToSend.exists() && !fileToSend.isDirectory()) {
// http 协议返回头
out.println("HTTP/1.0 200 OK");// 返回应答消息,并结束应答
out.println("Content-Type:" + contentType);
out.println("Content-Length:" + fileToSend.length());// 返回内容字节数
out.println();// 根据 HTTP 协议, 空行将结束头信息
FileInputStream fis = null;
try {
fis = new FileInputStream(fileToSend);
} catch (FileNotFoundException e) {
out.println("<h1>404错误!</h1>" + e.getMessage());
}
byte data[];
try {
data = new byte[fis.available()];
fis.read(data);
out.write(data);
} catch (IOException e) {
out.println("<h1>500错误!</h1>" + e.getMessage());
e.printStackTrace();
} finally {
out.close();
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
out.println("<h1>404错误!</h1>" + "文件没有找到");
out.close();
}
}
void printParams(String params) throws IOException {
if (params == null) {
return;
}
String[] maps = params.split("&");
for (String temp : maps) {
String[] map = temp.split("=");
System.out.println(map[0] + "==" + map[1]);
}
}
分享到:
相关推荐
本实验的主题是“多线程Web服务器的设计与实现”,这涉及到并发处理和网络通信的核心概念。下面将详细讨论相关知识点。 1. **多线程**:多线程是指在一个程序中可以同时执行多个独立的线程。在Web服务器中,多线程...
在Java中实现多线程Web服务器是一项常见的实践,因为Java提供了强大的多线程支持。 首先,我们来理解多线程的概念。在单线程环境中,程序执行是顺序的,一次只能做一件事。而多线程允许程序同时执行多个任务,每个...
java 多线程和服务器的源码,用于web服务器的java多线程控制
在IT领域,构建一个基于Java的多线程Web服务器是一项重要的技术挑战,它涉及到网络编程、并发处理以及HTTP协议的理解。下面将详细讲解这个主题。 首先,Java是一种跨平台的编程语言,它提供了丰富的库和工具来支持...
Java多线程Web服务器是一种基于Java技术构建的服务器,它利用多线程模型来处理并发的HTTP请求,以实现高效且可扩展的网络服务。在Java中,多线程是并发编程的重要工具,允许程序同时执行多个任务,这对于处理来自...
Java Socket 编程实现的简单多线程 WEB 服务器 在本文中,我们将详细介绍如何使用 Java 的 Socket 编程实现一个简单的多线程 WEB 服务器。 Socket 编程简介 Socket 编程是 Java 网络编程的基础,它允许开发者创建...
本文将深入探讨多线程Web服务器的概念、Java中的Socket编程以及如何通过实现Runnable接口来创建多线程。 多线程Web服务器的核心在于能够同时处理多个客户端请求,以提高服务效率和响应速度。在传统的单线程模型中,...
1. **Java多线程基础**:Java提供了两种创建线程的方式:继承Thread类和实现Runnable接口。在Web服务器源码中,通常会采用后者,因为这样可以避免单继承的限制,提高代码的可扩展性。 2. **Socket编程**:Web服务器...
【Java Web服务器基础】 在IT领域,Java Web服务器是一种用于处理HTTP请求并返回Web内容的软件。...此外,此项目也提供了一个动手实践的机会,有助于提高对HTTP协议、Java多线程以及服务器端编程的理解。
标题中的“TCP/IP多线程web服务器实现,Multi-Threaded Web Server java实现多网页请求访问”揭示了我们要讨论的核心技术点,即如何使用Java语言实现一个基于TCP/IP协议的多线程Web服务器。Web服务器的主要任务是...
### 计算机网络课程设计——《基于JAVA的多线程Web服务器》 #### 一、项目背景与目标 在本课程设计中,学生需要构建一个基于Java的多线程Web服务器,该服务器能够处理并发服务请求,并演示其能够向Web浏览器提供...
总结来说,这个实验涵盖了HTTP基础、多线程Web服务器的实现以及Java RMI的应用,这些都是构建复杂网络应用程序的基础。每个部分都至关重要,理解和掌握它们对于成为一名合格的IT专业人士至关重要。通过实践,你可以...
总之,多线程Web服务器在Java中实现的核心在于合理调度线程,高效处理并发请求,并确保线程安全。通过线程池、并发控制机制以及高效的I/O模型,我们可以构建出能应对高并发场景的Web服务器。在实际项目中,还应考虑...
本项目以Java作为编程语言,实现了这样一个多线程Web服务器,这为我们提供了深入理解网络通信、Java多线程以及HTTP协议的机会。 首先,我们要明白Java在Web开发中的角色。Java以其跨平台的特性,广泛应用于服务器端...
在实现多线程Web服务器时,我们需要创建一个主线程池,用于接收新的连接请求,然后将每个请求分配给一个工作线程来处理。每个工作线程负责读取请求、解析HTTP协议、执行相应的操作(如返回静态文件或执行动态脚本)...
标题中的“使用Java编写的一个简易多线程HTTP服务器”指的是一个使用Java编程语言实现的简单HTTP服务器,它利用了多线程技术来处理客户端的HTTP请求。在Java中,可以使用Socket编程接口来建立TCP连接,进而实现HTTP...
"简单Web服务器设计与实现" 本文主要介绍了简单Web服务器的设计与实现,涵盖了WWW的工作原理、HTTP协议、Java语言、Web服务器的设计与实现等方面的知识点。 WWW的工作原理基于客户机/服务器计算模型,由Web浏览器...
下面是一个简单的Java程序示例,用于实现一个基本的多线程Web服务器: ```java public class WebServer { public static void main(String[] args) { int PORT = 8080; ServerSocket server = null; Socket ...