/**
* Copyright (c) 2005-2012 https://github.com/zhangkaitao
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
package com.sishuok.chapter4.web.servlet.nonblocking;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
*
* 写数据客户端,{@link com.sishuok.chapter4.web.servlet.nonblocking.ReadServlet} 负责读
*
* <p>User: Zhang Kaitao
* <p>Date: 13-7-20 下午3:52
* <p>Version: 1.0
*/
@WebServlet(name = "readClientServlet", urlPatterns = "/readClient")
public class ReadClientServlet extends HttpServlet {
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Connection", "Keep-Alive");
resp.addHeader("Cache-Control", "private");
resp.addHeader("Pragma", "no-cache");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("正在读数据...");
resp.getWriter().flush();
resp.flushBuffer();
StringBuilder url = new StringBuilder("http://");
url.append(req.getLocalAddr());
url.append(":");
url.append(req.getLocalPort());
url.append(req.getContextPath());
url.append("/write");
HttpURLConnection conn = (HttpURLConnection) new URL(url.toString()).openConnection();
//设置是否从httpUrlConnection输入,默认true
conn.setDoOutput(true);
//get方式提交
conn.setRequestMethod("GET");
conn.connect();
InputStream is = new BufferedInputStream(conn.getInputStream());//此处可以使用非阻塞读(目前是阻塞读)
int count = 0;
int ch = -1;
while((ch = is.read()) != -1) {
count++;
if(count % (1024 * 100) == 0) {//读1024个字节暂停200毫秒 用于观察非阻塞写
System.out.println("客户端暂停读取1秒..,已读取:" + count + "个字节");
try{
Thread.sleep(1000L);
} catch (Exception e) {
}
}
//客户端可强行终止连接
//此处的目的是为了模拟出客户端主动关闭的情况,即服务器发送了1024*1000,但客户端只读取到1024*500,此时可能导致连接提前中断,服务器写失败
//需要注释掉后边的is.close();conn.disconnect();
// if(count >= (1024)) {
// System.out.println("客户端接收完1024 * 1000个字节");
// //这将导致服务器端可能还没写完数据,就遭遇了java.io.IOException: 您的主机中的软件放弃了一个已建立的连接
// //此时服务器端将回调WriteListener#onError
// is.close();
// conn.disconnect();
// break;
// }
}
is.close();
conn.disconnect();
resp.getWriter().write("\n客户端读数据完成...");
resp.getWriter().flush();
resp.flushBuffer();
}
}