如何创建一个Web服务器?

10

我知道已经有很多网络服务器存在了。

但是我想创建一个供学习目的使用。

这是值得我尝试去探究的东西吗?是否有任何关于此方面的指南或教程?


你忘了提及和标记编程语言。顺便说一下,第一步之一显然是:学习HTTP - BalusC
5个回答

9
在Java中:
创建一个ServerSocket并让其不断监听连接请求,当有连接请求时,通过解析HTTP请求头来处理它,获取所需的资源,并在发送回客户端之前添加一些头部信息。例如:
public class Server implements Runnable {

    protected volatile boolean keepProcessing = true;
    protected ServerSocket serverSocket;
    protected static final int DEFAULT_TIMEOUT = 100000;
    protected ExecutorService executor = Executors.newCachedThreadPool();

    public Server(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        serverSocket.setSoTimeout(DEFAULT_TIMEOUT);
    }

    @Override
    public void run() {
        while (keepProcessing) {
            try {
                Socket socket = serverSocket.accept();
                System.out.println("client accepted");
                executor.execute(new HttpRequest(socket));
            } catch (Exception e) {
            }
        }
        closeIgnoringException(serverSocket);
    }

    protected void closeIgnoringException(ServerSocket serverSocket) {
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException ignore) {
            }
        }
    }

    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        try {
            executor.execute(new WebServer(6789));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

final class HttpRequest implements Runnable {

    final static String CRLF = "\r\n";
    private Socket socket;

    public HttpRequest(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            processRequest();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    private void processRequest() throws Exception {
        DataOutputStream os = new DataOutputStream(socket.getOutputStream());
        BufferedReader br = new BufferedReader(new InputStreamReader(socket
            .getInputStream()));
        String requestLine = br.readLine();

        System.out.println();
        System.out.println(requestLine);

        List<String> tokens = Arrays.asList(requestLine.split(" "));
        Iterator<String> it = tokens.iterator();
        it.next(); // skip over the method, which should be "GET"
        String fileName = it.next();

        fileName = "." + fileName;

        FileInputStream fis = null;
        boolean fileExists = true;
        try {
            fis = new FileInputStream(fileName);
        } catch (FileNotFoundException e) {
            fileExists = false;
        }

        String statusLine = null;
        String contentTypeLine = null;
        String entityBody = null;
        String contentType = null;
        if (fileExists) {
            statusLine = "HTTP/1.0 200 OK";
            contentType = contentType(fileName);
            contentTypeLine = "Content-type: " + contentType + CRLF;
        } else {
            statusLine = "HTTP/1.0 404 NOT FOUND";
            contentType = "text/html";
            contentTypeLine = "Content-type: " + contentType + CRLF;
            entityBody = "<HTML>" + "<HEAD><TITLE>Not Found</TITLE></HEAD>"
                + "<BODY>" + statusLine + " Not Found</BODY></HTML>";
        }

        os.writeBytes(statusLine);
        os.writeBytes(contentTypeLine);
        os.writeBytes(CRLF);

        if (fileExists) {
            sendBytes(fis, os);
            fis.close();
        } else {
            os.writeBytes(entityBody);
        }

        String headerLine = null;
        while ((headerLine = br.readLine()).length() != 0) {
            System.out.println(headerLine);
        }
        os.close();
        br.close();
        socket.close();
    }


    private static void sendBytes(InputStream fis, DataOutputStream os)
            throws Exception {
        byte[] buffer = new byte[1024];
        int bytes = 0;

        while ((bytes = fis.read(buffer)) != -1) {
            os.write(buffer, 0, bytes);
        }
    }

    private static String contentType(String fileName) {
        if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
            return "text/html";
        }
        if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            return "image/jpeg";
        }
        if (fileName.endsWith(".gif")) {
            return "image/gif";
        }
        if (fileName.endsWith(".txt")) {
            return "text/plain";
        }
        if (fileName.endsWith(".pdf")) {
            return "application/pdf";
        }
        return "application/octet-stream";
    }
}

我应该将文件存储在哪里?另外,我可以用Web服务器做哪些有趣的事情? - Dave
你可以将文件存储在项目主目录中。你可以根据自己的想象做任何有趣的事情:这是一个基本的Web服务器,除了提供文件外什么也不做...如果你想学习关于Web服务器的知识,就修改它,研究它,尽一切可能去实现。 - Robert
哎呀,Java总是让所有事情变得如此容易,即使你想做一些困难的事情! - Ali

5
在Windows平台上用C++编写一个简单的Web服务器
希望这个链接能帮到你 ;) 其他选择:
  • CodePlex上可以找到一个模块化的Web服务器项目
  • 这篇文章从CodeGuru介绍了如何使用C#编写一个简单的Web服务器应用程序。

2

首先要了解TCP/IP和整个互联网协议套件

然后学习HTTP 1.0和1.1协议。

这些知识将帮助你理解如何从头开始创建一个Web服务器。


2

尝试使用boost中的asio!

Boost.Asio是一个跨平台的C++库,用于网络和低级I/O编程,提供了一致的异步模型,采用现代化的C++方法。


1

大多数脚本语言都具备编写Web服务器的能力,并且有很多示例。这条路线将为您提供一个温和的介绍。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接