Sockets JavaFX套接字处理

Sockets JavaFX套接字处理,sockets,javafx,Sockets,Javafx,要尝试说明这种情况,请执行以下操作: 我创建了一个SocketManager类。这扩展了JavaFX服务,旨在创建新线程(一个JavaFX任务,我已经扩展并称之为SocketListener),在其中处理特定的套接字连接 在SocketListener中,我有一个循环通过套接字监听输入(并回复客户机) 问题:SocketListener中的循环被阻塞(显然)。这意味着我永远不会在Socket Listener(扩展了JavaFX任务)的调用方法中找到“return”。 我很好奇应该实现什么模式,

要尝试说明这种情况,请执行以下操作:

我创建了一个SocketManager类。这扩展了JavaFX服务,旨在创建新线程(一个JavaFX任务,我已经扩展并称之为SocketListener),在其中处理特定的套接字连接

在SocketListener中,我有一个循环通过套接字监听输入(并回复客户机)

问题:SocketListener中的循环被阻塞(显然)。这意味着我永远不会在Socket Listener(扩展了JavaFX任务)的调用方法中找到“return”。 我很好奇应该实现什么模式,这样我就可以从SocketListener返回一个值,而不必中断与客户端保持连接的循环。我想到的一个想法是创建一个自定义事件,当每条消息通过套接字发送时触发,但我想确保我实现的任何东西都不只是“工作”,而是最佳的

下面是我引用的两个类的代码:

import javafx.concurrent.Service;
import javafx.concurrent.Task;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * The primary class for listening for and issuing communication over sockets in VDTS
 * applications.
 * WARNING: This class is blocking, and should be run in a separate thread.
 */
public class SocketManager extends Service<SocketMessage> {

    /**
     * The port that SocketManager instance will listen on.
     */
    int listenPort;

    /**
     * The ServerSocket instance used by SocketManager for receiving socket connections.
     */
    ServerSocket server;

    /**
     * Constructs a SocketManager and begins listening on the given port.
     * @param listenPort The port that the SocketManager instance will listen on.
     */
    public SocketManager(int listenPort){
        this.listenPort = listenPort;
        try {
            this.server = new ServerSocket(listenPort);
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
            //TODO
        }
    }

    /**
     * Returns the port currently being listened to by SocketManager instance.
     * @return the port being listened to.
     */
    public int getListenPort() {
        return listenPort;
    }

    /**
     * Sets a new port for the SocketManager instance to listen to. This will destroy
     * the current ServerSocket, ending any communication via the old instance. Use
     * with caution.
     * @param listenPort The new port this SocketManager instance will listen on.
     */
    public void setListenPort(int listenPort) {
        this.listenPort = listenPort;
    }

    @Override
    protected Task createTask() {
        String returnedMessage;
        Socket client;
        SocketListener messenger;
        while(true){
            try {
                client = null;
                client = server.accept();
                messenger = new SocketListener(client);
                new Thread(messenger).start();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
                //TODO
            }
        }
    }
}
导入javafx.concurrent.Service;
导入javafx.concurrent.Task;
导入java.io.IOException;
导入java.net.ServerSocket;
导入java.net.Socket;
/**
*通过VDT中的套接字侦听和发出通信的主要类
*应用程序。
*警告:此类正在阻塞,应在单独的线程中运行。
*/
公共类SocketManager扩展服务{
/**
*SocketManager实例将侦听的端口。
*/
int listenPort;
/**
*SocketManager用于接收套接字连接的ServerSocket实例。
*/
服务器套接字服务器;
/**
*构造SocketManager并开始侦听给定端口。
*@param listenPort SocketManager实例将侦听的端口。
*/
公共SocketManager(int-listenPort){
this.listenPort=listenPort;
试一试{
this.server=newserversocket(listenPort);
}捕获(IOEX异常){
System.out.println(例如getMessage());
//待办事项
}
}
/**
*返回SocketManager实例当前侦听的端口。
*@返回正在侦听的端口。
*/
public int getListenPort(){
返回listenPort;
}
/**
*为SocketManager实例设置要侦听的新端口。这将销毁
*当前ServerSocket,结束通过旧实例的任何通信。使用
*小心。
*@param listenPort此SocketManager实例将侦听的新端口。
*/
公共void setListenPort(int listenPort){
this.listenPort=listenPort;
}
@凌驾
受保护的任务createTask(){
字符串返回消息;
套接字客户端;
SocketListener信使;
while(true){
试一试{
client=null;
client=server.accept();
messenger=新的SocketListener(客户端);
新线程(messenger).start();
}捕获(IOEX异常){
System.out.println(例如getMessage());
//待办事项
}
}
}
}
另一个呢

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * An extension on javafx.concurrency.Task.
 * SocketListener is responsible for retrieving a message (string) from a client over
 * the socket and returning this string (Usually to a SocketManager).
 */
public class SocketListener extends javafx.concurrent.Task<String> {

    /**
     * Client socket which is referenced for persistent communication.
     */
    private final Socket client;

    /**
     * PrintWriter used to write to client.
     */
    private PrintWriter clientOut;

    //TODO This is a temporary property for testing, remove it;
    private int messageCount = 0;

    /**
     * Constructs a SocketListener given a client (Socket)
     * @param client
     */
    public SocketListener(Socket client){
        this.client = client;
        try {
            this.clientOut = new PrintWriter(client.getOutputStream(), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Listens for and returns the value of the message received over socket.
     * @return The message received from the client.
     * @throws Exception
     */
    @Override
    protected String call() throws Exception {
        String nextLine = null;
        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        //TODO remove in production should not require highfive
        clientOut.println("Just saying hi.");
        while ((nextLine = in.readLine()) != null) {
            this.messageCount++;
            clientOut.println("You've messaged me " + this.messageCount + " times.");
        }
        return "Socket closed.";
    }
}
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.PrintWriter;
导入java.net.Socket;
/**
*javafx.concurrency.Task上的扩展。
*SocketListener负责通过网络从客户端检索消息(字符串)
*套接字并返回此字符串(通常是到SocketManager)。
*/
公共类SocketListener扩展了javafx.concurrent.Task{
/**
*为持久通信引用的客户端套接字。
*/
私有最终套接字客户端;
/**
*PrintWriter用于写入客户端。
*/
私人印刷作家clientOut;
//TODO这是用于测试的临时属性,请将其删除;
private int messageCount=0;
/**
*在给定客户机(套接字)的情况下构造SocketListener
*@param客户端
*/
公共SocketListener(套接字客户端){
this.client=client;
试一试{
this.clientOut=新的PrintWriter(client.getOutputStream(),true);
}捕获(IOE异常){
e、 printStackTrace();
}
}
/**
*侦听并返回通过套接字接收的消息的值。
*@返回从客户端收到的消息。
*@抛出异常
*/
@凌驾
受保护的字符串调用()引发异常{
字符串nextLine=null;
BufferedReader in=新的BufferedReader(新的InputStreamReader(client.getInputStream());
//生产中的TODO删除不需要highfive
println(“只是打个招呼”);
而((nextLine=in.readLine())!=null){
这个.messageCount++;
println(“你给我发了信息”+this.messageCount+“次”);
}
返回“插座关闭”;
}
}

为什么不尝试使用其他选项?通过套接字输入和输出数据的标准库不是很高效(java.net)。您可以尝试Java,它将为您的代码提供更大的灵活性

NIO为您提供了启动连接的能力,因此您可以选择代码是否会阻止您的连接,但您必须使用循环。在回路内部,您可以观察到进行了什么类型的通信​​在两点之间,然后按照您的意愿处理通信。然而,如果你有更多的创造力,你可以在服务器端使用executors服务,从而导致其他线程只需要处理通信,剩下一个线程负责通信或交换数据

JavaFX是一种技术,它带来了开发丰富应用程序的强大工具。由于JavaFX被认为是一种不同类型的技术,并使用另一种方法,因此JavaFX(比如Swing)带来了一些工具来确保代码线程安全,这正是