希望有人可以对这一点有所了解,并提供一种解决方法,或阐明我在这里缺少的一些方法。
试图创建一个非常简单的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 套接字。
即使有什么背景导致异常也会很棒!
答案 0 :(得分:1)
接受线程永远不应该等待套接字的输入,它应该将数据交换委托给一个单独的线程,并立即返回到执行ServerSocket.accept(),就像this example末尾所描述的那样。对于高负载的服务器(数千个并发连接),该线程可能会消耗太多内存,因此可以使用异步IO。