在編寫一個測試方法時,須要用啓動一個程序監聽一個端口,測試發送的數據是事正常,可是老是出現兩個問題,一是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 判斷是否讀取完瀏覽器