网络编码的性能

时间:2016-10-09 17:27:22

标签: java networking network-programming

我正在尝试在JAVA中编写我的HttpServer。

一旦用户编写了URL,就会有一个简单的代码来创建套接字(服务器和客户端)以及读取和收集标头的信息。

我正在寻找一种可以操纵数据获取/收集的好方法(性能代码)。

在我写的代码中,我写道,这看起来很糟糕 也许谁可以帮我解释第三级尝试编写好的代码块?

例如,我认为if (headerTempData.contains("\r\n\r\n")) break;对于流式传输和从连接套接字收集数据将会变慢,因为我不知道将下载多少个标题行,并且对于它检查的所有门控信息

也许谁知道相关文献(书籍等)的其他要点可以帮助我理解http协议代码的良好性能,这对我很有帮助

谢谢!

具体的尝试块代码:

try (InputStream raw = socket.getInputStream()) {

    String headerTempData = "";

    // chain the InputStream to a Reader
    Reader reader = new InputStreamReader(raw);

    int c;
    while ((c = reader.read()) != -1) {
        headerTempData += (char) c;
        System.out.print((char) c);

        if (headerTempData.contains("\r\n\r\n"))
            break;
    }

    System.out.println("- - - - - - - - - - - - EOL - - - - - - - - - - - -");

}

所有代码示例:

package pk7HttpServer;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by Morris on 08/10/16.
 */
public class HTTPServer {


    public static void main(String[] args) {

        new HTTPServer().startServer();
    }

    public void startServer() {

        try (ServerSocket serverSocket = new ServerSocket(8080)) {

            System.out.println("Server is started");

            while (true) {
                Socket socket = serverSocket.accept();

                try {
                    try (InputStream raw = socket.getInputStream()) {

                        String headerTempData = "";

                        // chain the InputStream to a Reader
                        Reader reader = new InputStreamReader(raw);

                        int c;
                        while ((c = reader.read()) != -1) {
                            headerTempData += (char) c;
                            System.out.print((char) c);

                            if (headerTempData.contains("\r\n\r\n"))
                                break;
                        }

                        System.out.println("- - - - - - - - - - - - EOL - - - - - - - - - - - -");

                    }
                } catch (MalformedURLException ex) {
                    System.err.println(socket.getLocalAddress() + " is not a parseable URL");

                } catch (IOException ex) {
                    System.err.println(ex.getMessage());
                }
            }

        } catch (Exception ex) {
            System.out.println("error# " + ex.getMessage());
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你的解析逻辑有几个缺点。

  1. 发件人可能会以块的形式传输数据。这意味着尽管尚未收到整个输入,但read()可能会返回-1。如果尚未达到预期的数据结束,则必须实现逻辑以重新输入read()。
  2. 将每个字节转换为char(您没有提供要使用的字符集,因此您的代码在Windows和Linux机器上的行为方式不同)是一个耗时的操作。因此,您在收到的每个字节上调用contains()(这是另一个耗时的操作)。
  3. 我建议以块(例如1024字节)读取传入数据,聚合它,并且只有当您认为现在有足够的数据接收时才使用已定义的CharacterSet将字节数组转换为字符串。
  4. \ r \ n是Windows上的换行符。在其他平台上,这是不同的。
  5. 只要收到的数据小于包含调用的长度,它就永远不会成立。只有在收到足够的数据时才检查标题结尾。