用IO,NIO,MINA三种方式抓百度,返回结果大不同

发布于 2021-11-11 05:48:59 字数 5389 浏览 837 评论 6

采用阻塞IO,NIO,MINA三种方式去抓取百度首页,打印出首页的内容。我发现NIO和MINA返回的结果跟阻塞IO返回的结果不同,尤其是MINA,差别很大。JDK版本为1.6.0_29

首先是阻塞方式的IO去连接:

        Socket socket = new Socket("www.baidu.com", 80);
        OutputStream os = socket.getOutputStream();
        os.write("GET / HTTP/1.1rn".getBytes());
        os.write("Host:www.baidu.comrnrn".getBytes());
        os.flush();
       
        InputStream is = socket.getInputStream();
        String line = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
       
        while((line=br.readLine()) != null) {
            System.out.println(line);

        }

 

之后将返回的结果保存为一个html文件,a.html

 

第二次,使用NIO的方式抓取百度

            InetSocketAddress socketAddress = new InetSocketAddress(
                    "www.baidu.com", 80);

            channel = SocketChannel.open(socketAddress);
            //channel.configureBlocking(false);   使用阻塞或者非阻塞的方式返回结果都一样
           
            byte[] buf = "GET / HTTP/1.1rnHost:www.baidu.comrnrn".getBytes();
            ByteBuffer bb = ByteBuffer.allocate(buf.length);
            bb.put(buf);
            bb.flip();
            channel.write(bb);

            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (channel.read(buffer) != -1) {
                buffer.flip();
                if(buffer.limit() > 0) {
                    System.out.println(new String(buffer.array()));
                }
                buffer.clear();
            }

将返回结果保存为b.html

 

最后是用MINA:

        NioSocketConnector connector = new NioSocketConnector();
        DefaultIoFilterChainBuilder chain = connector.getFilterChain();

        chain.addLast("myChin", new ProtocolCodecFilter(
                new TextLineCodecFactory()));
       
        connector.setHandler(new ClientHandle());
        connector.setConnectTimeout(30);
        ConnectFuture cf = connector.connect(new InetSocketAddress("www.baidu.com",80));

        cf.awaitUninterruptibly();
        cf.getSession().getCloseFuture().awaitUninterruptibly();
        connector.dispose();

 

ClientHandle类:

public class ClientHandle extends IoHandlerAdapter {
    @Override
    public void messageReceived(IoSession session, Object message)
    throws Exception {
        System.out.println(message);
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        System.out.println(message);
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        session.write("GET / HTTP/1.0rn");

//        session.write("GET / HTTP/1.1rn");
//        session.write("Host:www.baidu.comrnrn");
    }
}

用MINA采用HTTP1.0和HTTP1.1的方式返回结果都是一样的。

将mina返回的结果保存为c.html

 

最后将这三个html都打开,对比正常的www.baidu.com页面,发现阻塞IO获取到的结果是正确的,和原始的baidu首页是一模一样,而NIO获取到的有一点点不同,主要是在格式上有一点不同。但是MINA差别就非常大了。从对比来看,阻塞IO返回的内容应该是完全正确的,NIO好像少了一点内容。

这里我弄不清楚的是,为什么NIO和阻塞IO获取的结果会不同,将NIO设置为阻塞的方式返回的结果还是跟阻塞IO有差别。而MINA则很离谱了,返回的结果跟原始的百度页面差很多,似乎是一些数据没获取到,不知道为什么。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

辞别 2021-11-17 20:44:44

NIO 收到那多余的部分其实是上一次的在bytebuffer中的缓存,

本王不退位尔等都是臣 2021-11-17 18:16:25

是什么问题呢、楼主解决了吗?@超级呆子

孤檠 2021-11-16 15:15:29

Mina获得数据可能只是一部分,得继续读取后面还有

终遇你 2021-11-16 08:48:58

使用mina时候看看编码转换问题是否有影响

网页是别人的,不好控制,调试起来不方便

或者你自己起个jsp界面然后用3中方式获取看看,

少女净妖师 2021-11-14 03:22:56

又试了一下NIO的方式,代码如下:

        InetSocketAddress ia = new InetSocketAddress("www.baidu.com",80);
        SocketChannel socket = SocketChannel.open(ia);
        String header = "GET / HTTP/1.1rnHost:www.baidu.comrnrn";
        byte[] buf = header.getBytes();
        ByteBuffer bb = ByteBuffer.allocate(buf.length);
        bb.put(buf);
        bb.flip();
        socket.write(bb);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while(socket.read(buffer) != -1) {
            buffer.flip();
            //if(buffer.limit() > 0) {
                System.out.print(new String(buffer.array()));
            //}
            buffer.clear();
        }

 

这回返回的内容,保存为html后打开,显示的结果跟正常的百度就非常类似了,但是却多收到了一些内容:

 

 

如果是阻塞IO,到红框那段后面就没有了,但是NIO收到的结果却多出了一些内容。

我不知道哪里有问题,请指教。

泛泛之交 2021-11-12 17:05:50

应该是你代码的问题

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文