【问题标题】:Read data from InputStream using Threads使用线程从 InputStream 读取数据
【发布时间】:2014-05-30 12:39:43
【问题描述】:

我尝试使用 InputStream 类中的 read() 方法,但它阻塞了线程,我尝试了 readLine() 方法也阻塞了线程。

在这些尝试之后,我使用了这个:

    public static void main(String[] args) throws IOException{
        Socket s = new Socket();
        String host = "";
        s.connect(new InetSocketAddress(host, 23));

        Response response = new Response(s);

        response .start();

        if(response .isInterrupted()){
            System.out.println(response .getSb().toString());
        }


    }

public class Response extends Thread {
    Socket s;
    BufferedReader s_in = null;
    InputStream in = null;
    private StringBuffer sb = new StringBuffer();

    public Response(Socket s){
        this.s = s;
    }

    @Override
    public void run() {
        try {
            s_in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            in = s.getInputStream();

            char ch;
            int i;


            while(!Thread.currentThread().isInterrupted()){
                i = s_in.read();
                ch = (char) i;
                System.out.print(ch);
                getSb().append(getSb());
            }

            System.out.print(getSb());

        } catch (IOException ex) {
            Logger.getLogger(Response.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public StringBuffer getSb() {
        return sb;
    }
}

public class Message extends Thread{
    Socket s;
    PrintWriter s_out = null;

    public Message(Socket s){
        this.s = s;
    }

    @Override
    public void run(){
        try {
            s_out = new PrintWriter(s.getOutputStream(), true);
        } catch (IOException ex) {
            Logger.getLogger(Message.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

但是当我运行应用程序时,套接字没有足够的时间将所有数据发送到 InputStream。

所以,我可能会验证流何时结束。开始阅读。

感谢您的帮助!

【问题讨论】:

    标签: java stream telnet


    【解决方案1】:

    我不知道您为什么不使用缓冲流,或者将此读取器放在它自己的线程中,因为它应该始终从套接字读取(或准备读取),这意味着阻塞。

    但是,使用您提供的代码,改善您的情况的最简单方法是读取直到没有更多字节可读取,这不是您实际在做的事情。执行for 循环时可能会输入更多字节。试试这个:

    int i;
    char c;
    while (in.available() > 0)
    {
        i = s_in.read();
        System.out.print(ch = (char)i);
        sb.append(ch);
    }
    

    它确实不能解决您的问题,因为您没有使用单独的线程来缓冲您的输入,并且您仍然可以在收到您期望获得的所有数据之前退出循环。

    【讨论】:

    • 对不起 MBraedley,变量“s_in”是一个 BufferedReader。我忘了把这个放在问题中。并感谢您帮助我。我会试试这个解决方案。
    • MBraedley 这个解决方案不起作用。没有打印任何内容,意味着我没有收到所有数据。你能解释一下我如何创建线程吗?一个用于从 InpuStream 读取所有数据,另一个用于使用 PrintWriter 发送数据。
    • This is a brief overview of threads。如果您还不熟悉线程,可能还有另一种解决方案可供查看。这个应用程序有主循环吗?如果是这样,您应该在循环开始时进行非阻塞读取(基本上是我提供的),在循环中执行您需要执行的所有其他操作,然后重新开始。如果它是一个单一的应用程序,那么您需要找出一种方法来了解您是否已经阅读了所有需要阅读的内容,这决定了您何时跳出阅读循环。
    • MBraedley 我刚刚编辑了这个问题,以便更清楚。像这样运行应用程序,我的意思是在主要方法中我仍然从 inputStream 获取任何数据。是的,我不熟悉线程,所以我不知道如何使用它们来读取数据。
    • 是的,你永远不会那样捕捉一切。你需要一些东西来告诉读取循环退出,基本上是永远读取,除非它接收到一个特定的信号,这可能是一个特殊的字符或字符串来通过连接。
    猜你喜欢
    • 1970-01-01
    • 2010-11-18
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多