Rob*_*ner 2 java sockets networking multithreading
我试图在java中编写一个简单的Web服务器.
现在我只有一个简单的程序,但id喜欢扩展它,以便它可以通过建立多个TCP连接服务多个浏览器.
我一直在阅读线程.我的理解是你可以创建一个新线程,这将继续完全像另一个程序.因此,使用新线程,可能就像有2个可以为2个浏览器服务的Web服务器,或者可以为x Web浏览器提供服务的x Web服务器.
我有点迷失在如何在java中创建新线程,并给每个新线程一个连接.
我的想法是,我会有一个这样的循环,它获得新的连接并将每个新连接传递给一个新的线程
// make new ServerSocket
while (true) {
Socket newConn = serverSocket.accept();
// make new thread, and pass in newConn
}
Run Code Online (Sandbox Code Playgroud)
谁能给我一些关于如何前进的指导?(如果我在某个地方犯了错误,请指出它.我对线程编程很新,所以它完全可能我没有正确理解它)
抢
编辑:
谢谢所有人.
我去写了一些东西,java教程帮了很多忙.
我现在有了一个新问题
我在新线程的run()方法中添加了一个循环,它包含10秒倒计时(使用Thread.sleep(1000)),只要服务器收到图像请求,所以我可以看到哪些线程正在运行.(index.html里面有4张图片)
所以我请求index.html页面,我的服务器工作正常.然后我打开了大约十几个新标签.我的期望是对index.html页面的请求是即时的,但是将图像发送到浏览器需要10秒钟(因为我放在那里的延迟),此时服务器将收到请求对于下一个index.html页面,依此类推.总的来说,我认为十二个index.html页面会立即提供,而4*12 = 36个图像需要10秒才能在所有标签上提供.
实际发生的是获得前4个图像需要10秒钟,接下来4个图像需要10秒钟等等.因此,我的服务器只是排队请求并一次处理一个页面,而不是服务多个网页.
我认为我的计划有问题.但我觉得我可能无法正确理解浏览器如何与服务器交互.我认为浏览器会在解析html页面时请求新对象.所以如果我打开十几页,我的服务器应该收到几十个请求.我尝试在FF中打开几个选项卡,然后在FF中打开几个窗口,但这没有帮助.
然而,当我打开IE,FF和Chrome时,我在不同的时间(相隔约2秒)要求index.html,看起来每个浏览器同时接收页面,换句话说,有一点,有提供12个不同的图像,每个浏览器4个
所以我想我正在寻找一些确认这是预期的行为?如果是这样,为什么我只能在打开3个不同的浏览器时看到这种行为,而不是在我打开多个标签时?
(对于那些问过的人,我计划明年参加一个网络课程,但我现在尝试做一些基本的东西.所以半自学,半个小时)
如果您正在寻找一些强大的在线寻找工作解决方案.
如果是出于学习目的,那么创建自己的.
有几种方法可以做到这一点.最简单的方法是从Java教程中获取:
import java.net.*;
import java.io.*;
public class MultiServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(-1);
}
while (listening)
new MultiServerThread(serverSocket.accept()).start();
serverSocket.close();
}
}
import java.net.*;
import java.io.*;
public class MultiServerThread extends Thread {
private Socket socket = null;
public MultiServerThread(Socket socket) {
super("MultiServerThread");
this.socket = socket;
}
public void run() {
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
}
您将在以下位置实现处理请求的逻辑:
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
Run Code Online (Sandbox Code Playgroud)
您可以通过将线程放在线程池中来优化代码,这样您就不必每次都创建新的线程.
以下部分是主观的,取决于请求的类型以及您对每个请求的处理方式.如果您有很多并发客户端请求,那么NIO就是您的选择.
如果您的请求很短,并且您有超过10个并发的请求,则创建一个池.
如果您的请求超过100,那么我会开始关注NIO.