带套接字的Java客户端/服务器应用程序?

我正在编写一个将被另一种语言(matlab)调用的java包。 如果我的matlab进程结束,我希望Java进程继续运行。 每当matlab再次启动时,它应该能够与现有的运行进程通信。 所以我认为我需要让Java应用程序通过客户端/服务器模型中的套接字进行通信。 我设想有一套简单的function:

  • startServer(主机,端口)
  • runCommand(服务器,命令……)
  • stopServer(主机,端口)

我之前从未做过这样的事情。 我是否以正确的方式思考它,或者是否有一种更简单的方法来构建可以独立于其父进程运行的应用程序? 这样做的最佳现代方式是什么(例如,有没有好的Apache软件包)? 任何人都可以提供一个简单的演示或指向我通过套接字与进程通信的教程吗?

[编辑]为了澄清一下,matlab能够实例化一个java对象并在其自身中运行java代码。 因此,matlab中的startServer()函数将运行java代码,该代码将检查java进程是否已在该端口上运行,如果没有,则启动服务器进程。

我并不依赖于使用套接字(如果不是很明显,我主要是一个matlab开发人员),所以如果有更简单的东西,我就是为了它。 我只需要能够独立于matlab运行,但让matlab控制这些进程(通过java)。

服务器侦听连接。 当客户端建立连接时。 客户端可以发送数据。 在当前示例中,客户端发送消息“Hi my server”。 要终止连接,客户端会发送消息“bye”。 然后服务器也发送消息“再见”。 最后,连接结束,服务器等待另一个连接。 这两个程序应该在同一台机器上运行。 但是,如果要在两台不同的计算机上运行它们,您可以简单地将地址“localhost”更改为运行服务器的计算机的IP地址。

服务器

import java.io.*; import java.net.*; public class Provider{ ServerSocket providerSocket; Socket connection = null; ObjectOutputStream out; ObjectInputStream in; String message; Provider(){} void run() { try{ //1. creating a server socket providerSocket = new ServerSocket(2004, 10); //2. Wait for connection System.out.println("Waiting for connection"); connection = providerSocket.accept(); System.out.println("Connection received from " + connection.getInetAddress().getHostName()); //3. get Input and Output streams out = new ObjectOutputStream(connection.getOutputStream()); out.flush(); in = new ObjectInputStream(connection.getInputStream()); sendMessage("Connection successful"); //4. The two parts communicate via the input and output streams do{ try{ message = (String)in.readObject(); System.out.println("client>" + message); if (message.equals("bye")) sendMessage("bye"); } catch(ClassNotFoundException classnot){ System.err.println("Data received in unknown format"); } }while(!message.equals("bye")); } catch(IOException ioException){ ioException.printStackTrace(); } finally{ //4: Closing connection try{ in.close(); out.close(); providerSocket.close(); } catch(IOException ioException){ ioException.printStackTrace(); } } } void sendMessage(String msg) { try{ out.writeObject(msg); out.flush(); System.out.println("server>" + msg); } catch(IOException ioException){ ioException.printStackTrace(); } } public static void main(String args[]) { Provider server = new Provider(); while(true){ server.run(); } } } 

客户端

 import java.io.*; import java.net.*; public class Requester{ Socket requestSocket; ObjectOutputStream out; ObjectInputStream in; String message; Requester(){} void run() { try{ //1. creating a socket to connect to the server requestSocket = new Socket("localhost", 2004); System.out.println("Connected to localhost in port 2004"); //2. get Input and Output streams out = new ObjectOutputStream(requestSocket.getOutputStream()); out.flush(); in = new ObjectInputStream(requestSocket.getInputStream()); //3: Communicating with the server do{ try{ message = (String)in.readObject(); System.out.println("server>" + message); sendMessage("Hi my server"); message = "bye"; sendMessage(message); } catch(ClassNotFoundException classNot){ System.err.println("data received in unknown format"); } }while(!message.equals("bye")); } catch(UnknownHostException unknownHost){ System.err.println("You are trying to connect to an unknown host!"); } catch(IOException ioException){ ioException.printStackTrace(); } finally{ //4: Closing connection try{ in.close(); out.close(); requestSocket.close(); } catch(IOException ioException){ ioException.printStackTrace(); } } } void sendMessage(String msg) { try{ out.writeObject(msg); out.flush(); System.out.println("client>" + msg); } catch(IOException ioException){ ioException.printStackTrace(); } } public static void main(String args[]) { Requester client = new Requester(); client.run(); } } 

如果您决定使用自定义套接字级协议,那么我建议您在java端使用JBoss Netty :

换句话说,Netty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。 它极大地简化并简化了TCP和UDP套接字服务器等网络编程。

听起来您需要Java服务器进程独立于Matlab进程。 因此,当Matlab进程启动/停止时,Java服务器继续运行。 Java服务器将等待传入连接,并处理多个连接,断开连接等。

这是编写Java套接字服务器的教程 (注意它是Java客户端/服务器套接字通信的更大教程的一部分)。

您将面临的一个挑战(我无法帮助您在这里做Matlab不知道)是创建或使用独立于平台的创建实际消息的方法,无论是使用二进制表示,XML(看起来像Matlab有一些XMLfunction) ) 或其他。

如果你说,matlab可以从内部运行java代码,那么就没有理由不能使用RMI在matlab和java服务器之间进行通信。 RMI比原始套接字编程容易得多。

简单的部分是教程: Sun的套接字教程教会了我需要了解的有关套接字编程的所有知识,并希望能为您做到。

我认为您需要澄清您对要支持的命令的思考,特别是第一和第三:

  • 如果Java进程没有运行,谁将响应你的startServer命令? 如果它正在运行,谁需要它? 🙂

  • 您当然可以实现stopServer命令。 但这有点像让你的电脑从墙上拉出自己的电源线。 我们回到上一个问题:如果服务器停止了,谁会听到启动命令?

据我了解,您需要的唯一远程操作是中间操作。

但是…套接字编程只是适度有趣。 您可以考虑查看RMI教程以获得替代方案。

您是否有任何理由不能将您的Java服务器实现为tomcat中的servlet集合? Tomcat提供了自动启动和保持服务器运行的所有工具,您可以非常轻松地实现SOAP服务或RESTful Web服务,这将有助于将您的matlab代码与Java代码分离。