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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1776457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:31:09  来源:igfitidea点击:

Java client/server application with sockets?

javasocketsclient-server

提问by griffin

I'm writing a java package that will be called by another language (matlab). If my matlab process ends, I want the Java process to keep running. Whenever matlab starts again, it should be able to communicate with the existing running process. So I think I need to have the Java application communicating through sockets in a client/server model. I envision having a simple set of functions:

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

  • startServer(host, port)
  • runCommand(server, command...)
  • stopServer(host, port)
  • 启动服务器(主机,端口)
  • 运行命令(服务器,命令...)
  • 停止服务器(主机,端口)

I have never done anything like this before. Am I thinking about it in the right way, or is there an easier way of building an application that can run independently of it's parent's process? What's the best modern way of doing this (e.g. are there any good Apache packages)? Can anyone provide a simple demo or point me to a tutorial on communicating with a process through sockets?

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

[Edit]For some clarification, matlab is able to instantiate a java object and run java code within itself. So the startServer() function in matlab would run java code that will check if a java process is already running on that port and if not, start the server process.

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

I'm not tied to using sockets by any means (in case it isn't obvious, I'm mostly a matlab developer), so if there's something easier, I'm all for it. I just need to be able to run things independently of matlab, but have matlab control those processes (through java).

我不以任何方式使用套接字(如果不明显,我主要是一个 matlab 开发人员),所以如果有更简单的东西,我完全支持。我只需要能够独立于 matlab 运行东西,但让 matlab 控制这些进程(通过 java)。

采纳答案by Sajad Bahmani

The server listens for a connection. When a connection is established by a client. The client can send data. In the current example the client sends the message "Hi my server". To terminate the connection, the client sends the message "bye". Then the server sends the message "bye" too. Finally the connection is ended and the server waits for an other connection. The two programs should be running in the same machine. however if you want to run them in two different machines, you may simply change the address "localhost" by the IP address of the machine where you will run the server.

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

The server

服务器

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

The client

客户端

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

回答by Brian Agnew

It sounds like you need the Java server process to be independent of the Matlab process. So when the Matlab process starts/stops, the Java server continues. The Java server will sit and wait for incoming connections, and handle multiple connections, disconnects etc.

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

Here's a tutorialfor writing a Java socket server (note it's part of a larger tutorial on Java client/server socket communication).

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

One challenge you will face (and I can't help you here being Matlab-unaware) is creating or using a platform-independent means of creating the actual message, whether that's using a binary representation, XML (looks like Matlab has some XML functionality) or other.

您将面临的一个挑战(我无法帮助您在这里不知道 Matlab)是创建或使用与平台无关的方式来创建实际消息,无论是使用二进制表示形式还是 XML(看起来 Matlab 具有一些 XML 功能)) 或其他。

回答by skaffman

If you decide to go with a custom socket-level protocol, then I can suggest that you use JBoss Nettyat the java end:

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

In other words, Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.

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

回答by Carl Smotricz

The easy part is the tutorial: Sun's Sockets Tutorialtaught me everything I needed to know about sockets programming, and will hopefully do for you too.

教程是最简单的部分:Sun 的套接字教程教会了我关于套接字编程所需的一切知识,希望对您也有帮助。

I think you need to clarify your thinking about the commands you want to support, in particular the first and 3rd:

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

  • If the Java process isn't running, who's going to respond to your startServercommand? And if it is running, who needs it? :)

  • You can certainly implement a stopServercommand. But that would be kind of like having your computer pulling its own power cord out of the wall. We return to the previous question: If the server's stopped, who'll hear the start command?

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

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

As I understand it, the only remote operation you need is the middle one.

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

However... socket programming is only moderately fun. You may consider looking at the RMI tutorialfor an alternative.

然而......套接字编程只是中等乐趣。您可以考虑查看RMI 教程以获取替代方法。

回答by Suppressingfire

Any reason that you can't just implement your java server as a collection of servlets in tomcat? Tomcat comes with all the tools to autostart and keep the server running, you can implement SOAP service or RESTful web services pretty easily which will help to decouple your matlab code from your java code.

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

回答by skaffman

If, as you say, matlab can run java code from within itself, then there should be no reason that you can't use RMIto communicate between matlab and java server. RMI is vastlyeasier than raw socket programming.

如果,如您所说,matlab 可以从自身内部运行 java 代码,那么您应该没有理由不能使用RMI在 matlab 和 java 服务器之间进行通信。RMI是大大高于原始套接字编程更简单。