在编写一个测试方法时,须要用启动一个程序监听一个端口,测试发送的数据是事正常,可是老是出现两个问题,一是Socked老是在OutputSteam.write()方法以前被关闭,可是没有使用代码调用Socket的Close方法,另外一个是在接收数据时,老是卡在InputSteam.read()方法处(通常发生在前一个Socket在写数据时异常中断后再次有新Socket链接时),得不到数据,直到发送端关闭Socket,下面是代码html
package com.zoro.example.subscribe.queue; import com.zoro.util.SendUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; /** * @author zoro * @version 1.0 */ public class TestSubscribeQueue { private static final Logger LOGGER = LoggerFactory.getLogger(TestSubscribeQueue.class); public static void main(String[] args) throws IOException { new Thread(new EventListener()).start(); } private static String test(InputStream is) { BufferedReader br = null; InputStreamReader isr = null; StringBuilder sb = new StringBuilder(); isr = new InputStreamReader(is); br = new BufferedReader(isr); String line = null; while (true) { try { line = br.readLine(); if (line == null || line.length() == 0) { break; } } catch (IOException e) { e.printStackTrace(); } sb.append(line); sb.append("\n"); line = null; LOGGER.debug("当前读取的数据:{}", sb.toString()); } return sb.toString(); } static class EventListener implements Runnable { private final ServerSocket ss; public EventListener() throws IOException { ss = new ServerSocket(8087); } @Override public void run() { while (true) { /* 这里获得的InputStream 不能在OutputStream返回数据以前关闭,由于InputStream关闭以后会致使Socket关闭,你说奇怪不奇怪,这样一来就不能正常返回数据了,报错说Socket已经关闭 */ try (Socket s = ss.accept(); InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream()) { LOGGER.debug("等待请求..."); LOGGER.debug("新请求进入"); if (s.isClosed() || !s.isConnected() || s.isInputShutdown()) { continue; } // String result = SendUtil.resolveInputStream(is); String result = test(is); LOGGER.debug("收到请求:{}", result); StringBuilder response = new StringBuilder(); response.append("HTTP/1.1 200 OK\r\n"); response.append("Content-Type:text/html\r\n"); response.append("\r\n"); response.append("123252321"); LOGGER.debug("即将返回数据:{}", response.toString()); if (!s.isClosed()) { LOGGER.debug("正在返回数据"); os.write(response.toString().getBytes()); os.flush(); } } catch (IOException e) { e.printStackTrace(); } } } } }
两天后发现新问题: InputStream在包装成BufferedReader整行读取时到http请求的最后一行还会继续向下一行读,可是发送端这时已经不发送数据了,形成服务端一直卡在这里等待java
BufferedReader.readLine()方法在读取文件只,由于文件最后会是一个-1 ,因此能够知道在哪里结束,但网络请求最后没有这个-1 因此在读了最后一行后不知道请求数据已经没有更多了,形成一直阻塞编程
http 请求(只讨论get 与post 两种方法),get 请求只有请求头,在读取到第一个空行时就能够结束,post请求有请求体,能够根据请求头中ContentLength 判断是否读取完浏览器