一个简单的服务器实现,采用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编写一个使用TCP协议传输文件的Socket,实现客户端向服务器端发送一个文件,服务器端接收之后按相同的文件名在指定的目录下保存文件
这是一个使用java编写的浏览器和服务器的源代码,里面包含了全部的代码,对于初学者来说有一定的帮助。
用java编写的web服务器 源代码及一些解释
用JAVA编写一个服务器端和客户端,使得客户端可以向服务器端发送数据,服务器端接收数据后把数据打印出来
用java编写的FTP服务器、客户端。服务器底层采用apache FTPserver的JAR包。客户端底层采用sun.net包。两者都可以独立使用。在myeclipse10.6里面编写,java版本是1.6。
用java编写的一个服务器,有两个类,一个是实现线程接口,来接受网页文件,然后输入。一个是监听9999接口
java编写的简易HTTP服务器
Java 游戏服务器 仿照网狐内核编写.zipJava 游戏服务器 仿照网狐内核编写.zip Java 游戏服务器 仿照网狐内核编写.zipJava 游戏服务器 仿照网狐内核编写.zip Java 游戏服务器 仿照网狐内核编写.zipJava 游戏服务器 ...
使用Java编写的一个简易多线程HTTP服务器 源代码写于2018年5月份,计算机网络课程的实验作业 代码bug较多,欢迎各位dalao指教
使用Java NIO编写高性能的服务器
java实现web服务器:(1) 连接:Web浏览器与Web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接建立成功。 (2) 请求:Web浏览器通过socket向Web服务器提交请求。HTTP的请求一般是...
java编写的代理服务器 学习工作的好参考 大家可以参考下
java编写的简单DNS服务器代码,可用于二次开发,或者作为测试
java编码规范文档JAVA编写服务器和客户端
代理服务器打开一个端口接收浏览器发来的访问某个站点的请求,从请求的字符串中解析出用户想访问哪个网页,让后通过URL对象建立输入流读取相应的网页内容,最后按照web服务器的工作方式将网页内容发送给用户浏览器 ...
这是我用java编写的一个单用户的聊天系统 需要则下载