Java - 在while(true)循环中重复的ServerSocket accept()方法

时间:2013-12-12 11:36:10

标签: java sockets webserver

希望有人可以对这一点有所了解,并提供一种解决方法,或阐明我在这里缺少的一些方法。

试图创建一个非常简单的Web服务器。

到目前为止,我有:

public class SocketTest {

    public static void main(String[] args) throws IOException {

        ServerSocket sock = new ServerSocket(9876);

        while(true) {

            System.out.println("Before");
            Socket conn = sock.accept();
            System.out.println("After");

            conn.close();

        }
    }
}

然后,项目运行后,输出窗口显示:

Before

这是我的期望,但是一旦我输入:

127.0.0.1:9876

在网络浏览器中,我最终得到:

Before
After
Before
After
Before
After
Before

显示。因此,浏览器显然多次连接到该端口,但只有第一个连接在其页眉中包含任何信息。


写这篇文章的时候,我已经决定再进行一些实验了,然后提出来:

public class SocketTest {

    public static void main(String[] args) throws IOException {

        ServerSocket sock = new ServerSocket(9876);

        while(true) {

            System.out.println("Before");
            Socket conn = sock.accept();
            System.out.println("After");

            Scanner sc = new Scanner(conn.getInputStream());

            System.out.println("BEFORE if...");

            if (sc.hasNext()) {

                System.out.println("INSIDE if...");

                String[] cnr = sc.nextLine().split("\\s+");
                System.out.println("Command: " + cnr[0] + "  -  URL: " + cnr[1]);

            } else {

                System.out.println("INSIDE ELSE!");

            }

            System.out.println("Closing...");

            conn.close();

            System.out.println("Closed!");
        }
    }
}

如果您编译并运行此代码,您会注意到,首次打开套接字上的页面时,您会重复打开套接字,但它也会在该行上挂起大约10秒钟:

if (sc.hasNext()) {

好像它正在观察InputStream()一段时间,看它是否包含任何信息..?

此外,如果我快速连续发送两个实际页面(或只是刷新页面),它会立即通过。

任何人都可以对此有所了解吗?

我可以如何删除一个永远不会实现的InputStream()的等待,或者我如何让它忽略 phantom 套接字。

即使有什么背景导致异常也会很棒!

1 个答案:

答案 0 :(得分:1)

接受线程永远不应该等待套接字的输入,它应该将数据交换委托给一个单独的线程,并立即返回到执行ServerSocket.accept(),就像this example末尾所描述的那样。对于高负载的服务器(数千个并发连接),该线程可能会消耗太多内存,因此可以使用异步IO。