2015-02-23 150 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