Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中实现基于UDP的线程服务器?_Java_Multithreading_Udp - Fatal编程技术网

如何在Java中实现基于UDP的线程服务器?

如何在Java中实现基于UDP的线程服务器?,java,multithreading,udp,Java,Multithreading,Udp,如何在Java中实现基于UDP的线程服务器 基本上,我想要的是将多个客户端连接到服务器,并让每个客户端都有自己的线程。唯一的问题是,我不知道如何检查客户机是否正在尝试连接到服务器并为其生成新线程 boolean listening = true; System.out.println("Server started."); while (listening) new ServerThread().start(); 在这种情况下,服务器将生成新线程,直到内存耗尽。 下面是Server

如何在Java中实现基于UDP的线程服务器

基本上,我想要的是将多个客户端连接到服务器,并让每个客户端都有自己的线程。唯一的问题是,我不知道如何检查客户机是否正在尝试连接到服务器并为其生成新线程

boolean listening = true;

System.out.println("Server started.");

while (listening)
    new ServerThread().start();
在这种情况下,服务器将生成新线程,直到内存耗尽。 下面是ServerThread的代码(我想这里需要一种机制,在客户端尝试连接之前暂停ServerThread的创建)

public ServerThread(String name) throws IOException 
{
    super(name);
    socket = new DatagramSocket();
}

因此,Java编程之父请提供帮助。

因为UDP是一种无连接协议,为什么需要为每个连接生成一个新线程?当您收到UDP数据包时,可能应该生成一个新线程来处理收到的消息

UDP连接不同于TCP连接。它们不会保持活动状态,这就是UDP的设计

下一个代码块的handlePacket()方法可以对接收到的数据执行任何操作。许多客户端可以向同一个UDP侦听器发送多个数据包。也许这会对您有所帮助

public void run() {
        DatagramSocket wSocket = null;
        DatagramPacket wPacket = null;
        byte[] wBuffer = null;

        try {
            wSocket = new DatagramSocket( listenPort );
            wBuffer = new byte[ 2048 ];
            wPacket = new DatagramPacket( wBuffer, wBuffer.length );
        } catch ( SocketException e ) {
            log.fatal( "Could not open the socket: \n" + e.getMessage() );
            System.exit( 1 );
        }

        while ( isRunning ) {
            try {
                wSocket.receive( wPacket );
                handlePacket( wPacket, wBuffer );
            } catch ( Exception e ) {
                log.error( e.getMessage() );
            }
        }
    }

你看过这个项目了吗?我相信它的一个例子都会告诉你如何使用它来设置基于UDP的服务器。如果这是一个真正的产品,我不建议你尝试从头开始设计自己的实现。你会希望使用一个库来实现这一点,这样你就不会在每个连接中使用一个线程,而是一个线程线程池。

我真的不认为有必要

这是学校的事,对吗

如果您需要跟踪客户机,您应该拥有每个客户机的本地表示(服务器上的客户机对象)。它可以处理您需要执行的任何特定于客户机的操作

在这种情况下,您需要能够找出消息是从哪个客户端发送的。(使用消息中的信息。)您可以将客户端保存在映射中

最有效的方法可能是在主线程中执行所有处理,除非需要执行的任何操作都可以“阻止”等待外部事件(或者如果一些应该发生的事情可能需要很长时间,而有些事情可能需要很短时间)

如果需要,客户机对象可能会在handleMessage()中启动一个新线程

您不应该启动多个服务器线程

服务器线程可以执行以下操作:

while(running) {
  socket.receive(DatagramPacket p);
  client = figureOutClient(p);
  client.handleMessage(p);
}

如果没有特定于客户端的事情需要关注,只需阅读消息并在消息到达时在一个线程中处理它们。

在一定程度上,此设计取决于每个完整的UDP“对话框”只需要单个请求和即时响应,无论是单个请求还是带有重传的响应,或者是否需要为每个客户端处理大量数据包

我编写的RADIUS服务器具有单请求+重传模型,并为每个传入的数据包生成一个线程

当每个
DatagramPacket
被接收时,它被传递给一个新线程,然后该线程负责发送回响应。这是因为生成每个响应所涉及的计算和数据库访问可能需要相对较长的时间,并且生成线程比使用其他机制更容易处理到达的新数据包,而旧数据包仍在处理中

public class Server implements Runnable {
    public void run() {
        while (true) {
            DatagramPacket packet = socket.receive();
            new Thread(new Responder(socket, packet)).start();
        }
    }
}

public class Responder implements Runnable {

    Socket socket = null;
    DatagramPacket packet = null;

    public Responder(Socket socket, DatagramPacket packet) {
        this.socket = socket;
        this.packet = packet;
    }

    public void run() {
        byte[] data = makeResponse(); // code not shown
        DatagramPacket response = new DatagramPacket(data, data.length,
            packet.getAddress(), packet.getPort());
        socket.send(response);
    }
}

对我来说,这闻起来像是家庭作业。我知道这是一个旧的Q,但你在听的时候做了一个循环,每次都以系统可能的速度创建新的DatagramSockets。你最终肯定会耗尽内存。这是一个好问题,应该使用ExecutorService来回答。只是好奇,但“w”前缀到底是什么意思?梅我是c-损坏的,但它看起来确实像是一个单词对齐的int或其他东西…B-)啊,w代表工作变量。这是他们在我工作的地方强制执行的惯例,我现在有一个习惯。工作变量以w开头,参数以p开头。因为响应程序只实现Runnable,所以需要给它一个线程:(new thread(new Responder(packet))).start()。不过,使用ExecutorService可以提供更好的线程管理。@thoughtcrimes我认为在我第一次编写此示例的源代码时,
ExecutorService
类并不存在。在
线程上的好位置
错误!在“为每个客户机处理大量数据包”的情况下,TCP是否因为其持久性而更好?
public class Server implements Runnable {
    public void run() {
        while (true) {
            DatagramPacket packet = socket.receive();
            new Thread(new Responder(socket, packet)).start();
        }
    }
}

public class Responder implements Runnable {

    Socket socket = null;
    DatagramPacket packet = null;

    public Responder(Socket socket, DatagramPacket packet) {
        this.socket = socket;
        this.packet = packet;
    }

    public void run() {
        byte[] data = makeResponse(); // code not shown
        DatagramPacket response = new DatagramPacket(data, data.length,
            packet.getAddress(), packet.getPort());
        socket.send(response);
    }
}