2015-02-23 190 views
0

我想在java中編寫一個簡單的http服務器。這裏是我到目前爲止的代碼:Java套接字寫入然後從套接字讀取

服務器:

import java.net.*; 
import java.io.*; 
import java.util.*; 
import java.util.regex.*; 

public class Server 
{ 
    static final int PORT = 8080; 
    final String REQUEST_FORMAT = "^GET (.*?) HTTP/1.1$"; 
    final Socket client; 

    public Server(Socket s) 
    { 
     client = s; 
    } 

    public void run() 
    { 
     try 
     (Scanner in = new Scanner(new InputStreamReader(client.getInputStream())); 
     PrintWriter out = new PrintWriter(client.getOutputStream(),true);) 
     { 
      String request = in.findInLine(Pattern.compile(REQUEST_FORMAT)); 
      System.out.println(request); 
      out.write("HTTP/1.1 200 OK"); 
     } 
     catch(Exception ex) 
     { 
      ex.printStackTrace();    
     } 
    } 

    public static void main(String []args) 
    { 
     try 
     (
     ServerSocket server = new ServerSocket(PORT); 
     Socket client = server.accept(); 
     ) 
     { 
      Server s = new Server(client); 
      s.run(); 
     } 
     catch(Exception ex) 
     { 
      ex.printStackTrace(); 
     } 
    } 
} 

客戶:

import java.net.*; 
import java.io.*; 
import java.util.*; 

public class Client 
{ 
    final int PORT = 8080; 
    String data = "GET /home/index.html HTTP/1.1"; 
    public Client() 
    { 
     try 
     (Socket socket = new Socket("127.0.0.1",PORT); 
     PrintWriter out = new PrintWriter(socket.getOutputStream(),true); 
     Scanner in = new Scanner(new InputStreamReader(socket.getInputStream()));) 
     { 
      out.print(data); 
      String header1 = in.next(); 
      System.out.println("header="+header1); 
      int status = in.nextInt(); 
      System.out.println("status="+status); 
      String message = in.next(); 
      System.out.println("message="+message); 
     } 
     catch(Exception ex) 
     { 
     } 

    } 

    public static void main(String []args) 
    { 
     Client c = new Client(); 
    } 
} 

目前客戶端只是寫了一個樣本請求到服務器,服務器寫入的樣本響應頭。但是,服務器似乎在讀取請求之後無限期地等待客戶端輸入,而無需繼續發送響應。請幫助解決這個問題。在

String request = in.findInLine(Pattern.compile(REQUEST_FORMAT)); 

回答

0

你的服務器模塊的原因是,該模式沒有發現流也沒有完成。

解決方案A:關閉插座在客戶方

out.print(data); 
socket.shutdownOutput(); 

這隻有你不想進一步使編寫在客戶方寫道。

溶液B

  1. 客戶:數據寫入後換行。

    out.print(data); 
    out.print("\r\n"); 
    out.flush(); 
    
  2. 服務器:使用Scanner.nextLine(),而是匹配器Scanner.findInLine的()

    String line = in.nextLine(); 
    Matcher matcher = Pattern.compile(REQUEST_FORMAT).matcher(line); 
    String request = null; 
    if(matcher.find()) { 
        //request = line.substring(matcher.start(),matcher.end()); 
        request = matcher.group();//is similar to the commented line above 
    } 
    
+0

但是,如果我在最後寫新行,這不是錯的。據我所知,HTTP GET請求最後沒有換行符? – PPGoodMan 2015-02-23 17:51:37

+1

@PP好心人你錯了。不要做出無證據的猜測。 – EJP 2015-02-23 18:01:38

+0

您是否試圖實現一個簡單的套接字服務器和套接字客戶端?它有用嗎?從那裏你可以做出改進,使它看起來像一個Http套接字服務器 – alainlompo 2015-02-23 18:43:35

2

如果您正在實施一個HTTP服務器,你需要實現HTTP協議。你沒有這樣做。您需要長時間瞭解RFC 2616,特別是有關內容長度標頭,Connection:close和分塊傳輸編碼的部分,這些不同的方式可以確定正在傳輸的內容的長度。

你也沒有在任何時間寫作線條。 HTTP中的行結束符是\r\n,,它不會出現在您的代碼中的任何位置。

還有其他問題。您的服務器將只接受一個客戶端,然後停止。它需要圍繞接受代碼進行循環,並且需要啓動一個新線程來處理每個連接。

+0

我沒有實現一個真正的HTTP服務器。我是一名學生,這個假設是一個'簡單的'HTTP服務器 - 幾小時值得分配。無論如何,謝謝你的幫助。 – PPGoodMan 2015-02-23 17:48:59

+1

您仍然需要行終止符,您仍然需要讀取行,並且您仍然需要爲每個服務器會話處理多個客戶端。如果您認爲在實現任何類型的HTTP服務器時可以忽略HTTP規範,那麼就錯了。 – EJP 2015-02-23 18:00:06

+0

是的,我需要行終止符。謝謝你指出。這是我的錯誤。我查看了[這個鏈接](http://www.jmarshall.com/easy/http/),但沒有完全閱讀,得出的結論是請求在最後沒有換行符。我還有很多要實現的東西,不僅僅是處理更多的客戶端,但我必須實現一個線程池來處理客戶端。但我認爲我會先做基礎,然後看看。非常感謝你的幫助。 – PPGoodMan 2015-02-24 03:53:04