一个简单的服务器实现,采用Java语言。
/**
*
*/
package iotest.serversocket;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Brandon B. Lin
*
*/
public class JHTTP extends Thread {
private File documentRootDirectory;
private String indexFileName = "index.html";
private ServerSocket server;
private int threadCount = 50;
public JHTTP(File documentRootDirectory, int port, String indexFileName)
throws IOException {
if (!documentRootDirectory.isDirectory()) {
throw new IOException(documentRootDirectory
+ " does not exist as a directory");
}
this.documentRootDirectory = documentRootDirectory;
this.indexFileName = indexFileName;
this.server = new ServerSocket(port);
}
public JHTTP(File documentRootDirectory, int port) throws IOException {
this(documentRootDirectory, port, "index.html");
}
public JHTTP(File documentRootDirectory) throws IOException {
this(documentRootDirectory, 80);
}
@Override
public void run() {
createThreadPools();
logServerInfo(server);
acceptConnection();
}
private void createThreadPools() {
for (int i = 0; i < threadCount; i++) {
Thread t = new Thread(new RequestProcessor(documentRootDirectory,
indexFileName));
t.start();
}
}
private void logServerInfo(ServerSocket server) {
System.out.println("Accepting connections on port "
+ server.getLocalPort());
System.out.println("Document Root: " + documentRootDirectory);
}
private void acceptConnection() {
while (true) {
try {
Socket request = server.accept();
RequestProcessor.processRequest(request);
} catch (IOException exception) {
}
}
}
public static void main(String[] args) {
File root = new File("F:\\Java\\document\\docs");
int port = 80;
startServer(root, port);
}
private static void startServer(File rootDirectory, int port) {
try {
JHTTP webServer = new JHTTP(rootDirectory, port);
webServer.start();
} catch (IOException e) {
System.out.println("Server could not start because of an "
+ e.getClass());
e.printStackTrace();
}
}
}
/**
*
*/
package iotest.serversocket;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
/**
* @author Brandon B. Lin
*
*/
public class RequestProcessor implements Runnable {
private static List<Socket> socketPool = new LinkedList<>();
private File documentRootDirectory;
private String indexFileName = "index.html";
public RequestProcessor(File documentRootDirectory, String inexFileName) {
if (documentRootDirectory.isFile()) {
throw new IllegalArgumentException(
"DocumentRootDirectory must be a directory, not a file");
}
this.documentRootDirectory = documentRootDirectory;
try {
this.documentRootDirectory = documentRootDirectory
.getCanonicalFile();
} catch (IOException exception) {
exception.printStackTrace();
}
if (inexFileName != null)
this.indexFileName = inexFileName;
}
public static void processRequest(Socket request) {
synchronized (socketPool) {
socketPool.add(socketPool.size(), request);
socketPool.notifyAll();
}
}
@Override
public void run() {
while (true) {
String version = "";
try (Socket connection = getRequestFromJobQueue()) {
Reader in = new InputStreamReader(new BufferedInputStream(
connection.getInputStream()), "ASCII");
String request = readRequest(in);
System.out.println(request);
OutputStream raw = new BufferedOutputStream(
connection.getOutputStream());
Writer out = new OutputStreamWriter(raw);
StringTokenizer stringTokenizer = new StringTokenizer(request);
String method = stringTokenizer.nextToken();
if (method.equals("GET")) { // GET
File requestedFile = getFileFromRequest(stringTokenizer);
version = getVersionFromRequest(stringTokenizer);
if (accessiable(requestedFile)) {// OK
processSucess(raw, requestedFile, version);
} else { // not file found
processFailure(out, ResponseState.FNF, version);
}
} else { // not GET
processFailure(out, ResponseState.NIP, version);
}
} catch (IOException exception) {
exception.printStackTrace();
}
}
}
private Socket getRequestFromJobQueue() {
synchronized (socketPool) {
while (socketPool.isEmpty()) {
try {
socketPool.wait();
} catch (InterruptedException exception) {
}
}
return socketPool.remove(0);
}
}
private String readRequest(Reader in) throws IOException {
StringBuffer requestLine = new StringBuffer();
int readByte;
while (true) {
readByte = in.read();
if (readByte == '\r' || readByte == '\n')
break;
requestLine.append((char) readByte);
}
return requestLine.toString();
}
private byte[] readRequestedFile(File requestedFile) throws IOException {
DataInputStream fis = new DataInputStream(new BufferedInputStream(
new FileInputStream(requestedFile)));
byte[] theData = new byte[(int) requestedFile.length()];
fis.readFully(theData);
fis.close();
return theData;
}
private File getFileFromRequest(StringTokenizer stringTokenizer) {
String fileName = stringTokenizer.nextToken();
if (fileName.endsWith("/")) {
fileName += indexFileName;
}
File theFile = new File(documentRootDirectory, fileName.substring(1,
fileName.length()));
return theFile;
}
private String getVersionFromRequest(StringTokenizer stringTokenizer) {
String version = "";
if (stringTokenizer.hasMoreTokens()) {
version = stringTokenizer.nextToken();
}
return version;
}
private void processSucess(OutputStream raw, File requestedFile,
String version) throws IOException {
byte[] theData = readRequestedFile(requestedFile);
String contentType = guessContentTypeFromRequest(requestedFile
.getName());
if (version.startsWith("HTTP")) {
writeHeader(new OutputStreamWriter(raw), ResponseState.OK,
new Content(contentType, theData.length));
}
raw.write(theData);
raw.flush();
}
private boolean accessiable(File requestedFile) throws IOException {
return requestedFile.canRead()
&& requestedFile.getCanonicalPath().startsWith(
documentRootDirectory.getPath());
}
private void processFailure(Writer out, ResponseState state, String version)
throws IOException {
if (version.startsWith("HTTP ")) {
writeHeader(out, state, new Content("text/html", -1));
}
writeHint(out, state);
}
private void writeHeader(Writer out, ResponseState state, Content content)
throws IOException {
out.write("HTTP/1.0" + state.getStateCode() + state.getHint() + "\r\n");
Date now = new Date();
out.write("Data: " + now + "\r\n");
out.write("Server: JHTTP/1.0 \r\n");
if (content.getContenLength() != -1) {
out.write("Content-length: " + content.getContenLength() + "\r\n");
}
out.write("Content-Type: " + content.getContentType() + "\r\n\r\n");
out.flush();
}
private void writeHint(Writer out, ResponseState state) throws IOException {
out.write("<HTML>\r\n");
out.write("<HEAD><TITLE>" + state.getHint() + "</TITLE>\r\n");
out.write("</HEAD>\r\n");
out.write("<BODY>");
out.write("<H1>HTTP Error " + state.getStateCode() + ": "
+ state.getHint() + "</H1>\r\n");
out.write("</BODY></HTML>\r\n");
out.flush();
}
public static String guessContentTypeFromRequest(String request) {
String exetension = getExtension(request);
switch (exetension) {
case "html":
case "htm":
return "text/html";
case "txt":
case "java":
return "text/plain";
case "gif":
return "image/gif";
case "class":
return "application/octet-stream";
case "jpg":
case "jpeg":
return "image/jpeg";
default:
return "text/plain";
}
}
public static String getExtension(String fileName) {
return fileName.substring(fileName.lastIndexOf('.')+1, fileName.length());
}
class Content {
private String contentType;
private int contenLength;
public Content(String contentType, int contentLength) {
this.contentType = contentType;
this.contenLength = contentLength;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public int getContenLength() {
return contenLength;
}
public void setContenLength(int contenLength) {
this.contenLength = contenLength;
}
}
}
/**
*
*/
package iotest.serversocket;
/**
* @author Brandon B. Lin
*
*/
public enum ResponseState {
OK(200, "OK"), FNF(404, "File Not Found"), NIP(501, "Not Implemented");
private int stateCode;
private String hint;
ResponseState(int stateCode, String hint) {
this.stateCode = stateCode;
this.hint = hint;
}
public int getStateCode() {
return stateCode;
}
public void setStateCode(int stateCode) {
this.stateCode = stateCode;
}
public String getHint() {
return hint;
}
public void setHint(String hint) {
this.hint = hint;
}
}
分享到:
相关推荐
java编写的游戏服务器java编写的游戏服务器 java编写的游戏服务器java编写的游戏服务器 java编写的游戏服务器java编写的游戏服务器 java编写的游戏服务器java编写的游戏服务器 java编写的游戏服务器java编写的游戏...
总结起来,使用Java编写客户端向服务器传输文件涉及到的主要知识点有:Java的Socket和ServerSocket类,网络通信的基本原理,文件的输入/输出流操作,以及可能涉及的多线程、异常处理和安全性策略。理解这些概念并能...
本项目涉及的是使用Java编写的一个简单的浏览器和服务器,这对于学习Java网络编程的初学者来说是一个很好的实践案例。 首先,我们要理解浏览器和服务器的基本工作原理。浏览器是客户端应用程序,用于向服务器发送...
下面,我们将深入探讨如何使用Java创建一个基本的Web服务器,并理解其背后的原理。 ### 1. Java Web服务器的基本结构 在提供的`WebServer.java`代码中,我们首先看到了对Java标准库中`java.io`和`java.net`包的...
在Java编程领域,创建一个服务器是一项基础且重要的任务,它涉及到网络编程和多线程的知识。这个特定的项目包括两个核心文件:`WebThread.java` 和 `WebServlet.java`,它们共同构成了一个简单的服务器框架。 首先...
java编写的简易HTTP服务器
标题中的“使用Java编写的一个简易多线程HTTP服务器”指的是一个使用Java编程语言实现的简单HTTP服务器,它利用了多线程技术来处理客户端的HTTP请求。在Java中,可以使用Socket编程接口来建立TCP连接,进而实现HTTP...
当有客户端连接时,`accept()`方法会返回一个新的Socket对象,我们可以用它来获取输入流和输出流,进而读取和发送数据。 客户端则需要创建一个Socket对象,指定服务器的IP地址和端口号,然后同样获取输入流和输出流...
Java 游戏服务器 仿照网狐内核编写.zipJava 游戏服务器 仿照网狐内核编写.zip Java 游戏服务器 仿照网狐内核编写.zipJava 游戏服务器 仿照网狐内核编写.zip Java 游戏服务器 仿照网狐内核编写.zipJava 游戏服务器 ...
【标题】:“用Java编写的简单聊天程序” 在IT领域,Java是一种广泛使用的面向对象的编程语言,以其“一次编写,到处运行”的特性而闻名。本项目是一个基于Java实现的简单聊天程序,它展示了如何利用Java进行网络...
本项目是个人使用JAVA编写的聊天程序,它实现了基本的即时通讯功能,用户之间可以进行文字聊天并发送表情,具有实时性的特点。 首先,我们要了解Java聊天程序的基础架构。在Java中,通常会采用Socket编程来实现网络...
java编写的简单DNS服务器代码,可用于二次开发,或者作为测试
java编写的代理服务器 学习工作的好参考 大家可以参考下
总的来说,Java编写的简易聊天系统是一个综合运用了网络编程、多线程、输入/输出流、用户界面设计等多个Java核心概念的项目。通过这个系统,开发者可以深入理解Java在网络应用中的实际运用,同时也能提升处理并发和...
这个名为"网络下载管理器"的程序,可能是用Java编写的一个工具,用于帮助用户更有效地管理和控制他们的网络下载。下载管理器通常具备以下功能: 1. **多任务下载**:允许用户同时下载多个文件,提高了下载效率。 2....