【问题标题】:Java Reopen ServerSocket for new connectionsJava 为新连接重新打开 ServerSocket
【发布时间】:2015-03-02 22:23:22
【问题描述】:

我有以下代码用于 java 回显服务器,它侦听传入请求并回复发送的文本。

public class EchoServer {
    int port;
    ServerSocket server;
    Socket client;
    BufferedWriter bw;
    BufferedReader br;

    EchoServer() throws IOException{
        int port = 1234;
        while(true){
            server = new ServerSocket(port);
            client = server.accept();
            bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
            br = new BufferedReader(new InputStreamReader(client.getInputStream()));

            bw.write(br.readLine());
            bw.newLine();
            bw.flush();

            bw.close();
            br.close();
            client.close();
            server.close();
        }
    }

    public static void main(String[] args)throws IOException{
        new EchoServer();
    }
}

但我认为这是低效的,因为每个对象都会在循环中重新创建。如果我将循环修改为以下

while(true){
        server = new ServerSocket(port);
        client = server.accept();
        bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
        br = new BufferedReader(new InputStreamReader(client.getInputStream()));

        bw.write(br.readLine());
        bw.newLine();
        bw.flush();
}

bw.close();
br.close();
client.close();
server.close();

我可以处理许多请求,但只能来自客户端。 我该怎么做才能获得以下行为:

  • 处理无限量的请求
  • 按顺序处理每个请求,一次只处理一个请求
  • 无需不必要地创建对象或关闭流/套接字
  • 没有线程

甚至可以在没有线程的情况下实现此行为,因为我不希望事情变得不必要地复杂。如果不可能,我怎么能用线程来实现呢?

提前致谢

【问题讨论】:

    标签: java multithreading sockets loops


    【解决方案1】:

    除非您转向非阻塞 NIO,否则您的目标是相互冲突的。要修复此当前代码,您需要:

    1. new ServerSocket(port) 行移到while 循环之前,并将close 移到它之后。
    2. 为每个接受的套接字启动一个新线程,以处理其 I/O。

    这是大多数 Java 服务器的工作方式。

    【讨论】:

    • OP 似乎不需要并发处理请求。见第二个要点。他的问题似乎是关于连续或至少在每次连接后关闭ServerSocket 的并发连接建立产品的缺乏。
    • @MarioRossi OP 需要“无限量的请求”和“按顺序处理每个请求,一次只处理一个请求”。这包括来自单个客户端的多个请求。如果没有多路复用 I/O 或阻塞模式下的线程,这是不可能的。
    【解决方案2】:

    ServerSocket 的全部意义在于您不必每次都创建它。将创建(和关闭)排除在循环之外。除其他外,这将导致同时发送连接请求的客户端排队并在下一次调用server.accept() 时提供服务。如果您在每个循环上关闭ServerSocket,则挂起的客户端队列将丢失。

    另一方面,如果您对创建对象如此反感,那么您可能不应该使用 Java 或任何其他 OOPL,因为它们的 API 会不断地创建和销毁对象。当您连接两个字符串时,您认为其中许多会发生什么?是什么让您相信创建对象的效率如此之低?如果您在 OOPL 中考虑这些想法来开发程序,那么从长远来看,您将使它们非常难以维护、脆弱并且可能效率较低。

    【讨论】:

    • 我认为有一个误解,我在创建和销毁对象方面没有问题,但是在不需要时这样做,在我的代码中,serversocket 不需要每次都重新创建循环运行
    • @danielr1996 如果您知道没有必要,为什么要这样做?
    • 发布答案时我不知道,但因为很多答案我现在知道了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多