⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webserver.java~3~

📁 网络实验:用JAVA语言实现WEB服务器功能。
💻 JAVA~3~
字号:
package fu;import java.io.*;import java.net.*;import java.util.*;/* * Web服务器类 * 		实现一个多线程的Web服务器,响应客户机GET、HEAD和POST方法的请求, * 返回响应的HTML、GIF或JPGE文件及相应的404、405、505等出错信息。 */public class WebServer {        public static int MAXCONN = 10;// 最大连接数,常量        public static int POST = 8080;// 服务器端口,常量        private ServerSocket serverSocket;// 服务器套接字        private static int numOfConn = 0;// 连接数        private Socket[] connectionSocket;// 连接套接字        /*         * 内部类 连接线程 为每个客户端连接建立新线程,实现HTTP请求的解析并进行HTTP响应。         */        private class ConnectionThread extends Thread {                int id;// 连接序号                BufferedReader reader;// Input流                DataOutputStream writer;// Output流                String requestLine;// 请求行                String rlMethod;// 请求方法                String rlFileName;// 请求文件名                String rlHttpProtocolVersion;// 请求HTTP协议版本号                File requestFile;// 存放请求文件                byte[] fileInBytes;// 存放请求文件的字节格式                int statusCode;// 响应状态代码                String statusLine;// 响应状态行                String headerLine;// 响应首部行                String hlContentType;// 响应内容类型                String hlContentLength;// 响应内容长度                String spaceLine;// 空行                // /<summary>构造方法 初始化id</summary>                // /<parameter="id">连接序号</parameter>                public ConnectionThread(int id) {                        addConn();                        this.id = id;                }                // /<summary>重写Thread.run()方法,运行线程</summary>                public void run() {                        System.out.println("Connection" + id + " Start!");                        // 建立输入输出流,读取请求报文的请求行                        try {                                reader = new BufferedReader(new InputStreamReader(                                                connectionSocket[id].getInputStream()));                                writer = new DataOutputStream(connectionSocket[id]                                                .getOutputStream());                                while (requestLine == null) {                                        requestLine = reader.readLine();                                }                                statusCode = parseRequestLine();// 解析请求行得出状态码                                statusLine = statusMsg(statusCode);// 根据状态码得出状态行                        } catch (IOException e) {                                System.out.println("That's an I/O Exception!\n"                                                + e.getMessage());                                statusCode = 400;                                statusLine = statusMsg(statusCode);                        }                        // 生成首部行和空行                        if (statusCode == 200) {                                hlContentType = getContentType();                                hlContentLength = getContentLength();                                headerLine = hlContentType + hlContentLength;                        }                        spaceLine = "\r\n";                        httpResponse();// 向客户终端套接字发送HTTP响应报文                        // 断开连接                        try {                                System.out.println("Connection" + id + " Finish!");                                if (connectionSocket[id] != null) {                                        connectionSocket[id].close();                                        connectionSocket[id] = null;                                        delConn();                                }                        } catch (IOException e) {                                System.out.println("That's an I/O Exception!\n"                                                + e.getMessage());                        }                }                // /<summary>向客户终端套接字写HTTP响应</summary>                private void httpResponse() {                        try {                                writer.writeBytes(statusLine);// 写状态行                                // 非正常状态代码时生成错误页面                                if (statusCode != 200) {                                        byte[] errorFile = "<html><head></head><body><p>ERROR!</body></html>"                                                        .getBytes();                                        writer.writeBytes(spaceLine);                                        writer.write(errorFile);                                } else {                                        // POST方法时写首部行和POST成功页面的实体                                        if (rlMethod.compareToIgnoreCase("POST") == 0) {                                                byte[] postFile = "<html><head></head><body><p>Post Success!</body></html>"                                                                .getBytes();                                                writer.writeBytes("Content-Type:text/html\r\n");                                                writer.writeBytes("Content-Length:" + postFile.length                                                                + "\r\n");                                                writer.writeBytes(spaceLine);                                                writer.write(postFile);                                        }                                        // GET方法时写首部行和请求文件的实体                                        if (rlMethod.compareToIgnoreCase("GET") == 0) {                                                writer.writeBytes(headerLine);                                                writer.writeBytes(spaceLine);                                                writer.write(fileInBytes);                                        }                                        // HEAD方法时仅写状态行                                }                        } catch (IOException e) {                                System.out.println("That's an I/O Exception!\n"                                                + e.getMessage());                        }                }                // /<summary>获得响应内容类型字符串</summary>                // /<return>响应内容类型字符串</return>                private String getContentType() {                        int index = requestLine.lastIndexOf('.');                        String type = requestLine.substring(index + 1);                        if (type.compareToIgnoreCase("html") == 0) {                                return ("Content_Type:text/html\r\n");                        } else if (type.compareToIgnoreCase("gif") == 0) {                                return ("Content_Type: image/gif\r\n");                        } else if (type.compareToIgnoreCase("jpg") == 0) {                                return ("Content_Type: image/jpge\r\n");                        } else {                                return ("Content_Type: text/text\r\n");                        }                }                // /<summary>获得响应内容长度字符串</summary>                // /<return>响应内容长度字符串</return>                private String getContentLength() {                        long length = requestFile.length();                        return ("Content-Length: " + length + "\r\n");                }                // /<summary>根据状态码生成</summary>                // /<parameter="statusCode">响应状态码</return>                // /<return>响应内容类型字符串</return>                private String statusMsg(int statusCode) {                        String statusWord;                        switch (statusCode) {                        case 200:                                statusWord = "OK";                                break;                        case 404:                                statusWord = "Not Found";                                break;                        case 405:                                statusWord = "Method Not Allowed";                                break;                        case 505:                                statusWord = "HTTP Version not supported";                                break;                        default:                                statusWord = "Bad Request";                        }                        return (rlHttpProtocolVersion + " " + statusCode + " " + statusWord + "\r\n");                }                // /<summary>解析请求报文的请求行</summary>                // /<return>响应内容状态码</return>                private int parseRequestLine() {                        try {                                StringTokenizer tokenized = new StringTokenizer(requestLine);                                rlMethod = tokenized.nextToken();                                rlFileName = tokenized.nextToken();                                rlHttpProtocolVersion = tokenized.nextToken();                                if (!checkMethod()) {                                        return (405);                                }                                if (!checkFileName()) {                                        return (404);                                }                                if (!checkHttpProtocolVersion()) {                                        return (505);                                }                                return (200);                        } catch (NullPointerException e) {                                System.out.println(e.getMessage());                                return (400);                        }                }                // /<summary>检查请求方法是否合法</summary>                // /<return>布尔值</return>                private boolean checkMethod() {                        if (rlMethod.compareToIgnoreCase("GET") != 0                                        && rlMethod.compareToIgnoreCase("POST") != 0                                        && rlMethod.compareToIgnoreCase("HEAD") != 0) {                                return (false);                        } else {                                return (true);                        }                }                // /<summary>检查请求文件名是否合法</summary>                // /<return>布尔值</return>                private boolean checkFileName() {                        if (rlFileName.startsWith("/")) {                                rlFileName = rlFileName.substring(1);                        }                        try {                                requestFile = new File(rlFileName);                                fileInBytes = new byte[(int) requestFile.length()];                                FileInputStream fileReader = new FileInputStream(requestFile);                                fileReader.read(fileInBytes);                        } catch (FileNotFoundException fnfe) {                                System.out.println("Can't find File!\n" + fnfe.getMessage());                                return (false);                        } catch (IOException ioe) {                                System.out.println("That's an I/O Exception!\n"                                                + ioe.getMessage());                                return (false);                        }                        return (true);                }                // /<summary>检查请求HTTP协议版本是否合法</summary>                // /<return>布尔值</return>                private boolean checkHttpProtocolVersion() {                        if (rlHttpProtocolVersion.compareToIgnoreCase("HTTP/1.0") != 0                                        && rlHttpProtocolVersion.compareToIgnoreCase("HTTP/1.1") != 0) {                                return (false);                        } else {                                return (true);                        }                }                // /<summary>锁定方法增加连接数</summary>                private synchronized void addConn() {                        numOfConn++;                }                // /<summary>锁定方法减少连接数</summary>                private synchronized void delConn() {                        numOfConn--;                }        }        // /<summary>构造方法 初始化套接字</summary>        public WebServer() {                try {                        serverSocket = new ServerSocket(POST, MAXCONN);// 建立服务套接字,绑定端口                } catch (IOException e) {                        System.out.println("Can't creat server socket!\n" + e.getMessage());                }                connectionSocket = new Socket[MAXCONN];// 生成连接套接字                for (int i = 0; i < connectionSocket.length; i++) {                        connectionSocket[i] = null;                }                System.out.println("WebServer Start!");        }        // /<summary>使监听套接字处于监听状态,监听到连接后新建连接线程并启用</summary>        public void listen() {                for (int i = 0; i < connectionSocket.length; i++) {                        // 连接数满时提示连接已满 暂停响应                        if (numOfConn >= MAXCONN) {                                System.out.println("Connection is full!");                                return;                        } else {                                try {                                        if (connectionSocket[i] == null) {                                                connectionSocket[i] = serverSocket.accept();// 监听                                                new ConnectionThread(i).start();// 新建线程并启用                                        }                                } catch (IOException e) {                                        System.out.println("That's an I/O Exception!\n"                                                        + e.getMessage());                                }                        }                }        }        // /<summary>main入口,创建实例并使之处于监听状态</summary>        public static void main(String args[]) {                WebServer webServer = new WebServer();                System.out.println("WebServer Listening!");                while (true) {                        webServer.listen();                }        }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -