我是初学者学习套接字编程并试图在Java中实现简单的Sinatra类库。 while循环以客户端套接字为关闭或不((!this.client.isClosed())),到目前为止,它是工作响应最小的请求,如“GET/HTTP/1.1”,直到客户端关闭连接,while循环去无限循环,并采取所有的CPU周期,我也试图添加额外的条件检查可用性客户端的InputStream返回-1(意思是关闭?),而(!this.client.isClosed()& &(reader.available( )!= -1))。循环服务线程在客户端关闭套接字后不会中断
WebServer.java
public void start(){
try{
while(true){
// accept and add incoming socket connection to client bulks
this.clients.put(++requestNumber, this.server.accept());
// service client request in Service thread
Service service = new Service(this);
service.start();
}
}
catch(IOException ioe){
System.out.println(ioe.getMessage());
}
finally{
// TODO: close server socket here
}
}// end start
Service.java
@Override
public void run(){
while(!this.client.isClosed()){
System.out.println("read request");
// parse http request
this.parser.parse();
String method = this.parser.getMethod();
String path = this.parser.getPath();
String httpVer = this.parser.getHttpVersion();
System.out.println("[METHOD] : "+method);
System.out.println("[PATH] : "+path);
System.out.println("[HTTP VERSION] : "+httpVer);
// match request with specified handler in handlers bulk
for(RequestHandler handler:this.server.handlers){
if(handler.getMethod().equals(method)){
if(handler.getPath().equals(path)){
System.out.println("send response\n=============");
// serve request
handler.handle(this.reader, this.writer);
}
}
}// end for loop
// debug only
try{Thread.currentThread().sleep(3000);}catch(InterruptedException ie){}
}// end while loop
// not get executed after client disconnect
System.out.println("exit service thread");
// remove client socket in client sockets bulk
server.clients.remove(requestId);
}// end run
HttpParser.java
// start HttpParser
public class HttpParser{
private BufferedInputStream in;
private String initial;
private String header;
public HttpParser(BufferedInputStream in){
this.in = in;
}
public void parse(){
System.out.println("parse request");
// pattern to match both \r\n or \n
Pattern pattern = Pattern.compile("\r?\n", Pattern.DOTALL);
Matcher match = null;
Scanner scanner = null;
StringBuilder requestBuffer = new StringBuilder("");
String request = "";
int nread = 0, nlength = 0;
try{
scanner = new Scanner(in).useDelimiter(pattern);
while((in.available() != -1) && scanner.hasNext()){
// read line from request
String line = scanner.next();
// break while loop if find empty line "\r\n\r\n" or "\n\n"
if(line.isEmpty()){break;}
// append line to buffer
requestBuffer.append(line+"\r\n");
}
// get full request from buffer
request = requestBuffer.toString();
System.out.println("[REQUEST]\n"+request);
// get initial header from request
match = Pattern.compile("^.*?\r\n").matcher(request);
if(match.find()){
// assign initial header to initial member
this.initial = match.group();
System.out.println("[INITIAL HEADER]\n"+this.initial);
}
}
catch(IOException ioe){}
}// end parse
// get method from initial header
public String getMethod(){
Pattern pattern = Pattern.compile("(^.*?)\\s+");
Matcher match = pattern.matcher(this.initial);
if(match.find()){
return match.group(1);
}
return "GET";
}
// get path from initial header
public String getPath(){
Pattern pattern = Pattern.compile("^.*?\\s+(.+?)\\s+");
Matcher match = pattern.matcher(this.initial);
if(match.find()){
return match.group(1);
}
return "/";
}
// get http version from initial header
public String getHttpVersion(){
Pattern pattern = Pattern.compile("^.*?\\s+.+?\\s+HTTP/(\\d\\.\\d)\\s.*");
Matcher match = pattern.matcher(this.initial);
if(match.find()){
return match.group(1);
}
return "1.1";
}
}
// end HttpParser
主类Jciw.java
import java.io.*;
// start Jciw
public class Jciw{
public static void main(String[] args){
WebServer webServer = new WebServer(8000);
webServer.handle_request("GET", "/", new RootGetHandler());
webServer.handle_request("POST", "/", new RootPostHandler());
webServer.start();
}
// start RootGetHandler
public static class RootGetHandler extends RequestHandler{
@Override
public void handle(InputStream reader, OutputStream writer){
try{
writer.write(("Hello GET request\n").getBytes());
writer.flush();
}
catch(IOException ioe){
}
}
}
// end RootGetHandler
// start RootPostHandler
public static class RootPostHandler extends RequestHandler{
@Override
public void handle(InputStream reader, OutputStream writer){
try{
writer.write(("Hello POST request\n").getBytes());
writer.flush();
}
catch(IOException ioe){
}
}
}
// end RootPostHandler
}
// end Jciw
运行与浏览器蚂蚁,使测试请求,请登录:
run:
[java] read request
[java] parse request
[java] [REQUEST]
[java] GET/HTTP/1.1
[java] Host: localhost:8000
[java] User-Agent: Mozilla/5.0 (X11; Linux i686; rv:22.0) Gecko/20100101 Firefox/22.0 SeaMonkey/2.19
[java] Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[java] Accept-Language: en-US,en;q=0.5
[java] Accept-Encoding: gzip, deflate
[java] Connection: keep-alive
[java]
[java] [INITIAL HEADER]
[java] GET/HTTP/1.1
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
从客户端关闭标签或断开后它会inifinite循环althought客户端套接字已经关闭,而应该(this.client.isClosed()!)评估为false,服务线程永远不会退出,请登录:
[java] read request
[java] parse request
[java] [REQUEST]
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
[java] read request
[java] parse request
[java] [REQUEST]
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
[java] read request
[java] parse request
[java] [REQUEST]
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
[java] read request
[java] parse request
[java] [REQUEST]
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
[java] read request
[java] parse request
[java] [REQUEST]
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
[java] read request
[java] parse request
[java] [REQUEST]
[java]
[java] [METHOD] : GET
[java] [PATH] :/
[java] [HTTP VERSION] : 1.1
[java] send response
[java] =============
你不需要任何的。当你在正常流程中遇到它时,你只需要对EOS做出正确反应。 – EJP 2014-11-25 20:49:16