如何使客户端-服务器 Java 应用程序在一个端口上发送消息但在另一个端口上接收消息?

How do I make a client-server Java application to send messages on one port but receive them on another?

我目前正在尝试制作一个应用程序,该应用程序将使用一个端口向服务器发送消息,但将在另一个端口接收消息。但是,根据我遵循的教程,看起来连接到服务器的行为是端口发挥作用的地方,我的客户端正在同一端口上接收和发送消息。我如何才能让它在一个端口上发送但在另一个端口上接收?

这是我认为与客户端相关的代码(我放了一些看起来无关的东西,因为我认为它们是通过在一个端口上接收但在另一个端口上发送而改变的东西,并忽略评论关于替换 inetaddress,这只是我在 gui 中实现它的工作):

public void startRunning(){
    try{
        connectToServer();
        setupStreams();
        whileChatting();

    }catch(EOFException eofException){
        showMessage("\n Client terminated connection");

    }catch(IOException ioException){
        ioException.printStackTrace();
    }finally{
        closeStuff();
    }

}



//connect to server
private void connectToServer() throws IOException{
    showMessage("Attempting connection... \n");
    connection = new Socket(InetAddress.getByName(serverIP), 480);//replace serverIP with ipTextField.getText or set serverIP to equal ipTextField.getText? Same with port number.
    showMessage("Connected to:  " + connection.getInetAddress().getHostName() );
}


//set up streams to send and receive messages
private void setupStreams() throws IOException{
    output = new ObjectOutputStream(connection.getOutputStream());
    output.flush();
    input = new ObjectInputStream(connection.getInputStream());
    showMessage("\n Streams are good!  \n");
}


//while talking with server
private void whileChatting() throws IOException{
    ableToType(true);
    do{
        try{
            message = (String) input.readObject();
            showMessage("\n" + message);
        }catch(ClassNotFoundException classNotfoundException){
            showMessage("\n Don't know that object type");
        }

    }while(!message.equals("SERVER - END"));
}

//send messages to server
private void sendMessage(String message){
    try{
        output.writeObject("CLIENT - " + message);
        output.flush();
        showMessage("\nCLIENT - " + message);
    }catch(IOException ioException){
        messageWindow.append("\n something messed up ");
    }

}


//change/update message window
private void showMessage(final String m){
    SwingUtilities.invokeLater(
        new Runnable(){
            public void run(){
                messageWindow.append(m);
            }
        }
    );

}

EDIT/UPDATE:为了帮助澄清一些事情,这里有一些更多的信息。发送第一条消息的设备连接到一个传感器,当该传感器检测到某些东西时,它会向另一个设备发送信息。接收设备在不同的端口发回一条消息,告诉原始发送设备如何响应。让我们将这两个设备命名为 "reporter-action taker" 和 "decision maker-commander"。

如果你想使用 TCP/IP 套接字,你不能使用一个套接字发送,另一个套接字读取。这不是他们的目的。

如果您使用集中式分布式算法(server/client 通信),您必须将服务器设置为使用 ServerSocket class 侦听单个套接字端口:然后服务器会尝试通过以下方式接受客户端那个插座。

示例:

ServerSocket listener = new ServerSocket(Port)
While (true) {
    new Clienthandler(listener.accept());
}

服务器将侦听该端口,当客户端尝试连接到该端口(如果被接受)时,服务器将启动其处理程序。在此处理程序构造函数上,客户端使用的 Socket 对象通过参数接收,然后可用于获取编写器和 readers。此处理程序 class 上的 reader 将是客户端 class 和 vice-versa 上的编写器,也许这就是您正在寻找的内容。

您关于以这种方式使用两个端口的问题有点奇怪。您声明您有一个客户端和一个服务器,并且它们应该在不同的端口上进行通信。

只是为了澄清一下,请将服务器想象成一个带有连续多个挂钩的夹克挂架。服务器侦听的每个端口代表一个挂钩。当谈到客户端服务器关系时,客户端或夹克知道在哪里可以找到它的钩子,但是钩子是盲目的,不知道在哪里可以找到夹克。

现在,客户端选择一个端口或一个钩子并连接到它。连接就像有两个管道的管道。一个用于客户端将数据传送到服务器,另一个用于将数据从服务器发送回客户端。建立连接后,可以双向传输数据。这意味着我们只需要在服务器上打开一个端口,就可以将数据从客户端发送到服务器,也可以从相反的方向发送数据。

之所以只在服务器上打开一个开放端口供客户端连接,是因为在普通客户端计算机上很难保持连接的开放端口。普通桌面用户将在几个防火墙后面阻止传入连接。如果不是这种情况,客户端可能会被恶意病毒攻击得毫无意义。

继续使用双端口解决方案,我们不能将其称为客户端服务器连接。它更像是点对点连接或类似的东西。但是,如果这是你想要做的,首先连接的应用程序必须首先告诉其他应用程序使用什么 ip 和端口进行连接,它可能还想提供某种令牌,用于连接回来时配对新的传入连接。

您应该注意,在大多数情况下进行这样的实现并不是一个好主意,因为它会使客户端和服务器应用程序之间的简单数据传输变得非常复杂。