Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 如何在不阻止其他请求的情况下侦听套接字输入_Java_Multithreading_Sockets - Fatal编程技术网

Java 如何在不阻止其他请求的情况下侦听套接字输入

Java 如何在不阻止其他请求的情况下侦听套接字输入,java,multithreading,sockets,Java,Multithreading,Sockets,我的标题可能不是最具描述性的,但我将尝试展示尽可能多的代码,希望它能帮助大家更好地理解我的问题。下面是我的项目客户端如何查询服务器以获取信息。这是一个典型请求的示例: private String GENERATEGROUPKEY() { /* `out` is a PrintWriter using the sockets output stream */ out.println("GENERATEGROUPKEY"); try { /* `i

我的标题可能不是最具描述性的,但我将尝试展示尽可能多的代码,希望它能帮助大家更好地理解我的问题。下面是我的项目客户端如何查询服务器以获取信息。这是一个典型请求的示例:

private String GENERATEGROUPKEY()
{
    /* `out` is a PrintWriter using the sockets output stream */
    out.println("GENERATEGROUPKEY");

    try
    {
        /* `in` is a BufferedReader using the sockets input stream */
        String response = in.readLine();
        String[] temp = response.split(" ");

        return temp[1];
    }
    catch (IOException ex)
    {
        return null; // throw connection error to client
    }
}
我的问题是,在任何时候,服务器都可以通过同一个套接字向客户端发送一条未经请求的消息,其中包含信息(将其视为聊天客户端接收消息)。我不成功的想法是创建一个线程来侦听这样的消息,只要我们不在另一个查询的中间,但是这也是不成功的,因为即使我中断了这个线程,它仍然占用了应该转到客户端查询的消息。
private String GENERATEGROUPKEY()
{
    out.println("GENERATEGROUPKEY");
    listenThread.interrupt(); // block listenThread from recieving response

    try
    {
        String response = in.readLine();
        String[] temp = response.split(" ");

        listenThread = new PulseThread(in); // we're done, so allow 
        listenThread.start();
        return temp[1];
    }
    catch (IOException ex)
    {
        listenThread = new PulseThread(in); // we're done, so allow
        listenThread.start(); 
        return null; // throw connection error to client
    }
}
下面就是
listenThread
的确切含义

public class PulseThread extends Thread
{
    private BufferedReader in;

    public PulseThread(BufferedReader in)
    {
        this.in = in;
    }

    @Override
    public void run()
    {
        while (true)
        {
            if (Thread.currentThread().isInterrupted())
            {
                break;
            }
            try
            {
                String line = in.readLine();
                System.out.println(line);
                String[] params = line.split(" ");
                if (params[0].equals("PULSED"))
                {
                    NotificationManager.sendNotification("You have been pulsed!", "Pulsed by: " + params[1]);
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}

我以前的印象是,在<代码>中间的线程> BufferedReader < /代码>的阻塞调用中,用<代码>读行()/代码>只会取消阻塞调用,除非我做了其他错误。

任何帮助都将不胜感激,谢谢


编辑:所以在这句话上面的几行中查看我的假设,似乎中断线程并不会取消
readLine()
。我想中断线程的想法是行不通的。正确的方法是什么?

这里的一般模式是,您需要一个线程处理套接字的输出(等待时阻塞),然后将消息发送到请求它们的正确对象

我喜欢并在多个项目中成功使用的一个实现是将随机生成的ID添加到“请求”中,作为通用头的一部分(也包括消息类型),并让服务器始终在响应中镜像该ID,它允许客户端将请求与响应关联起来,而不必关心它是什么类型的消息

具体来说,类似于带有两个公共函数的
SocketMessenger
类:
sendRequest(类型、正文、回调)
registerUnsolicitedHandler(类型、回调)

sendRequest
使用
type
和随机生成的ID构建消息头,将其添加到待处理回复列表中以及对回调函数的引用,然后将完成的消息发送到服务器

registerUnsolicitedHandler
按照其名称执行操作,并将回调函数添加到传入消息没有ID时要使用的消息类型映射中


在处理传入消息的单独线程中,它反序列化传入数据以从报头获取类型和ID,如果消息具有ID,它将搜索挂起的回复列表,并使用消息体调用相应的回调(可能是在主线程上安排的,我会忽略一些细节,如锁定),否则,它将在未经请求的处理程序列表中搜索指定类型并调用该回调。

With,err?它在哪里说中断线程会取消它被阻塞的I/O操作?@EJP这不是一个多线程问题吗?我不确定在一个合法且独特的问题上的-1是否合适,但我离题了。Javadocs说,我引用,“如果这个线程在可中断通道上的I/O操作中被阻塞,那么通道将被关闭。”这对我不适用吗?如果不是的话,我可能的解决方案是什么,因为我不知道我需要做什么。@Headline实际引用如java类中所述。BufferedReader可能正在引发异常,但由于您没有对其执行任何操作,因此您不会知道。此外,如果您正在使用通道,并且您中断正在读取该通道的线程,它将关闭该通道。。。没有别的东西可以从那个频道读到。