美文网首页Android开发Android开发经验谈程序员
Socket请求中readLine()方法引发的思考

Socket请求中readLine()方法引发的思考

作者: 碎碎想 | 来源:发表于2018-12-01 17:31 被阅读6次

    背景:
    今天没事自己模拟socket请求时发现了一个问题:

    
    //测试代码
    public static void http(String path) throws Exception {
        URL url = new URL(path);
        final String host = url.getHost();
        //如果指明了端口,则拿到端口,否则是-1
        int port = url.getPort();
        int defaultPort = url.getDefaultPort();
        final String file = url.getFile();
        Socket socket = new Socket(host, port == -1 ? defaultPort : port);
        InputStream is = socket.getInputStream();
        final BufferedReader br = new BufferedReader(new InputStreamReader(is));
        final OutputStream os = socket.getOutputStream();
    //开启一个线程用来读取数据
       new Thread(){
            @Override
            public void run() {
                String line;
                try {
                    while ((line = br.readLine()) != null){
                        Log.e("TAG",line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    //开启一个线程用来发送数据
       new Thread(){
           @Override
           public void run() {
               SystemClock.sleep(10000);
               try {
                   //请求行
                   os.write(("GET "+file+" HTTP/1.1\r\n").getBytes());
                   os.write(("Host: "+host+"\r\n").getBytes());
                   os.write(("\r\n").getBytes());
                   os.flush();
               }catch (Exception e){               }
    
           }
       }.start();
    
    /*   //请求行
        os.write(("GET "+file+" HTTP/1.1\r\n").getBytes());
        os.write(("Host: "+host+"\r\n").getBytes());
        os.write(("\r\n").getBytes());
        os.flush();*/
    
    
    }
    

    通过代码都能看到:
    我用了两种测试方式:
    第一次:开启一个线程用来读取数据,发送数据没有在子线程中发送,但是是在读取数据方法的下面。按照常理来说这样的代码会先执行读取数据的方法。结果通过断点调试发现是先执行的发送数据的方法,然后执行的读取数据的方法。 这里可能就会有人说了开启线程需要少量的时间。好,那么我就有了第二次测试。
    第二次(如上面代码):我把发送数据的代码也在z线程中执行,并且在该线程中睡10秒之后在执行发送数据的代码,结果还是和上面一样:先执行的发送数据的代码,然后再执行的读数据的方法。

    针对上面问题其实有一个误解,就是对readLine()方法的误解。 误以为readLine()是读取到没有数据时就返回null。而实际上readLine()是一个阻塞函数。当没有数据读取时,就会造成IO阻塞,这个方法就会一直阻塞在这里。所以只有等发送数据的方法执行完之后,readLine()才会读取到数据,接着下面的才会正常执行。

    相关文章

      网友评论

        本文标题:Socket请求中readLine()方法引发的思考

        本文链接:https://www.haomeiwen.com/subject/etercqtx.html