0

在 Java 中创建独立服务器时(不使用像 tomcat/jetty 这样的容器),保持服务运行而不结束的各种技术是什么?

我已经看到人们在哪里使用 ServerSocket(因为您可能会与服务进行通信),并且他们使用 ServerSocket.accept() 阻塞直到它收到消息。这通常在一个while循环中完成:

while(...) {
   serverSocket.accept();
}

http://docs.oracle.com/javase/6/docs/api/java/net/ServerSocket.html#accept()

这是唯一的方法吗?如果没有,还有哪些其他方法以及它的优点/缺点?

是否有任何库可以帮助您构建自己的服务,或者它几乎是您自己的。

4

3 回答 3

2

有各种库可以帮助您在 Java 中推出自己的 Windows/Unix 服务:

如何保持应用程序运行取决于应用程序的实际需求。如果您的应用程序是服务器,您通常会想要监听传入连接,这通常涉及某种阻塞/轮询。您如何再次执行此操作取决于您要构建的服务器类型。在通用解决方案中,您已经提到了 ServerSocket 类及其方法 accept()。另一种可能性是使用 java.nio 并实现一个反应器,它提供一个可以一次处理多个连接的单线程服务器(有关详细信息,请参见http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf) ,但可能有点难以掌握和调试。

于 2012-05-30T15:25:01.163 回答
1

您可能想要的是多线程服务器。每次服务器接受连接时,服务器都会创建一个线程来处理向该客户端发送/接收。如果您不在服务器中使用线程,它一次只能处理一个连接。因此,正如您的意思,服务器无限循环并侦听传入连接:

while(true){
    serverSocket.accept();
    ClientHandler c = new ClientHandler(serverSocket);

每次接受连接时,都会创建一个 ClientHandler 类的实例。此类实现 Runnable,并在该套接字上使用 getInputStream 和 getOutputStream 循环传入消息:

public class ClientHandler implements Runnable{
DataInputStream in;
DataOutputStream out;

//ClientHandler constructor
   public ClientHandler(Socket s) throws IOException{
        in= new DataInputStream(socket.getInputStream());
        out=new DataOutputStream(socket.getOutputStream());
        thread.start();
}

运行方法:

public void run() { 
   while(true){
       String temp="";
       while ((temp = (String) in.readUTF()) != null){ // Read from the input stream each iteration. When temp is not null a message is recived             
            System.out.println(temp);

请注意,上面的代码没有考虑到可能发生的不同异常,而且非常基础。但它应该让您对如何实现使用 Sockets 的服务器有一个基本的了解。

于 2012-05-30T14:35:37.137 回答
1

对于快速解决方案(仅在测试环境中!),您可以使用通常被称为“企业循环”的东西(因为它在生产系统中经常出现):

while (true) 
    try {
        // do something
    } catch (Throwable t) {
        // maybe log
    }

但是,这在生产代码中不是很好的风格。(参见 [1] 对该成语的模仿)

要创建服务,您需要此 answer中的库之一。

如果您“只需要多线程”,请查看 Java 并发框架。我强烈建议阅读Java Concurrency in Practice,因为多线程不仅仅是启动另一个线程,而且错误很难调试。

[1] http://blog.antiblau.de/2016/01/26/java-enterprise-loop/

于 2016-01-26T14:15:39.803 回答