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

时间:2009-11-21 19:25:46

标签: java sockets client-server

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

  • startServer(主机,端口)
  • runCommand(server,command ...)
  • stopServer(主机,端口)

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

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

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

6 个答案:

答案 0 :(得分:27)

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

服务器

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();
    }
}

答案 1 :(得分:2)

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

Here's a tutorial用于编写Java套接字服务器(请注意它是Java客户端/服务器套接字通信的更大教程的一部分)。

你将面临的一个挑战(我无法帮助你成为Matlab-unaware)是创建或使用独立于平台的创建实际消息的方法,无论是使用二进制表示,XML(看起来像Matlab some XML functionality)或其他。

答案 2 :(得分:2)

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

  

换句话说,Netty是NIO的客户   服务器框架,使快速   并且易于开发网络   协议服务器等应用程序   和客户。它大大简化了   简化网络编程等   作为TCP和UDP套接字服务器。

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

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

  • 如果Java进程未运行,谁将响应您的startServer命令?如果它正在运行,谁需要它? :)

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

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

然而......套接字编程只是中等乐趣。您可以考虑查看the RMI tutorial替代方案。

答案 5 :(得分:1)

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