正文

简单的HTTP服务器和客户端2006-05-09 16:09:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/sword2008/13786.html

分享到:

这是服务器部分
import java.net.*;
import java.io.*;
import java.util.*;

public class HTTPServer 
{
String serverName;
  String Version;
  int serverPort;

  // 构造一个server,并运行
  public static void main(String args[])
  {
   HTTPServer server = new HTTPServer("HTTPServer", "1.0", 80);
   server.run();
  }
  // 定义server的名字、版本号、端口
  public HTTPServer(String name, String version, int port) 
  {
   this.serverName = name;
   this.Version = version;
   this.serverPort = port;
  }
 
  public void run() 
  {
   // 显示名字和版本号
                System.out.println(serverName+" version ");
   try 
   {
    // 得到服务监听端口
    ServerSocket server = getServerSocket();
   
    do 
    {
     // 等待连接请求
     Socket client = server.accept();
     // 为连接请求分配一个线程
     (new HTTPServerThread(client)).start();
    }while(true);
   } 
   catch(Exception e) 
   {
    e.printStackTrace();
    System.exit(1);
   }
  }
 
  //服务器的构造方法,
  //我们可以对其构造方法进行扩展,
  //参考JSSE技术一章中的SSL扩展
  ServerSocket getServerSocket() throws Exception 
  {
   return new ServerSocket(serverPort);
  }
}




class HTTPServerThread extends Thread 
{
  Socket client;

  public HTTPServerThread(Socket client) 
  {
   this.client = client;
  }

  public void run() 
  {
   try 
   {
    describeConnectionInfo(client);

    BufferedOutputStream outStream = new 
BufferedOutputStream(client.getOutputStream());
//HTTPInputStream是自定义的过滤流
    HTTPInputStream inStream = new HTTPInputStream(client.getInputStream());

    //得到请求头
    HTTPRequest request = inStream.getRequest();
    //显示头信息
    request.log();
    //只处理GET请求
    if(request.isGetRequest())
     processGetRequest(request,outStream);
    System.out.println("Request completed. Closing connection.");
    //非持久性
    client.close();
   }
   catch(IOException e) 
   {
    System.out.println("IOException occurred .");
    e.printStackTrace();
   }
  
  
}
 
  // Display info about the connection
void describeConnectionInfo(Socket client) 
{
   //服务端主机名
   String destName = client.getInetAddress().getHostName();
   //服务端IP地址
   String destAddr = client.getInetAddress().getHostAddress();
   //服务端端口
   int destPort = client.getPort();
   //打印信息
   System.out.println("Accepted connection to "+destName+" ("+destAddr+")"+" on port "+destPort+".");
  }
 
  // 处理GET请求
  void processGetRequest(HTTPRequest request,BufferedOutputStream outStream)
    throws IOException 
    {
   String fileName = request.getFileName();
   File file = new File(fileName);
   // Give them the requested file
   if(file.exists()) sendFile(outStream,file);
   else System.out.println("File "+file.getCanonicalPath()+" does not exist.");
  }
  //  HTTP 1.0 回应
  void sendFile(BufferedOutputStream out,File file) 
  {
   try 
   {
    DataInputStream in = new DataInputStream(new FileInputStream(file));
    int len = (int) file.length();
    byte buffer[] = new byte[len];
    in.readFully(buffer);
    in.close();
    out.write("HTTP/1.0 200 OK\r\n".getBytes());
    out.write(("Content-Length: " + buffer.length + "\r\n").getBytes());
    out.write("Content-Type: text/HTML\r\n\r\n".getBytes());
    out.write(buffer);
    out.flush();
    out.close();
    System.out.println("File sent: "+file.getCanonicalPath());
    System.out.println("Number of bytes: "+len);
   }
   catch(Exception e)
   {
    try 
    {
     out.write(("HTTP/1.0 400 " + "No can do" + "\r\n").getBytes());
     out.write("Content-Type: text/HTML\r\n\r\n".getBytes());
    }
    catch(IOException ioe) 
    {
    }
    System.out.println("Error retrieving "+file);
   }
  }
}


// 实现读客户端请求的帮助类
class HTTPInputStream extends FilterInputStream 
{
public HTTPInputStream(InputStream in) 
{
   super(in);
  }
  // 读一行
  public String readLine() throws IOException 
  {
   StringBuffer result=new StringBuffer();
   boolean finished = false;
   //回车符
   boolean cr = false;
   do 
   {
    int ch = -1;
    ch = read();
    if(ch==-1) return result.toString();
    result.append((char) ch);
    //去掉最后的'\n'
    if(cr && ch==10)
    {
     result.setLength(result.length()-2);
     return result.toString();
    }
    //读到回车符,设置标识
    if(ch==13) cr = true;
    else cr=false;
   } while (!finished);
   return result.toString();
  }
  // 得到所有的请求
  public HTTPRequest getRequest() throws IOException 
  {
   HTTPRequest request = new HTTPRequest();
   String line;
   do 
   {
    line = readLine();
    //将请求填入容器
    if(line.length()>0) request.addLine(line);
    else break;
   }while(true);
   return request;
  }
}

// 客户端请求的封装类
class HTTPRequest 
{
Vector lines = new Vector();

  public HTTPRequest() 
  {
  }
  public void addLine(String line) 
  {
   lines.addElement(line);
  }
  // 判断是否是Get请求
 boolean isGetRequest() 
 {
   if(lines.size() > 0) 
   {
    String firstLine = (String) lines.elementAt(0);
    if(firstLine.length() > 0)
     if(firstLine.substring(0,3).equalsIgnoreCase("GET"))
      return true;
   }
   return false;
  }
  // 从请求中解析到文件名
  String getFileName() 
  {
   if(lines.size()>0) 
   {
    //得到vector中第一个元素
    String firstLine = (String) lines.elementAt(0);
    //得到文件名
    //根据http消息格式
    String fileName = firstLine.substring(firstLine.indexOf(" ")+1);
    int n = fileName.indexOf(" ");
    //URL在两个空格之间
    if(n!=-1) fileName = fileName.substring(0,n);
   
    //去掉第一个'/'
    try 
    {
     if(fileName.charAt(0) == '/') fileName = fileName.substring(1);
    } 
    catch(StringIndexOutOfBoundsException ex) {}
   
    //默认首页
    //类似于'http://localhost:80'的情况
    if(fileName.equals("")) fileName = "index.htm";
    //类似于'http://localhost:80//'的情况
    if(fileName.charAt(fileName.length()-1)=='/')
     fileName+="index.htm";
    return fileName;
   }else return "";
  }
  // 显示请求信息
  void log() 
  {
   System.out.println("Received the following request:");
   for(int i=0;i<lines.size();++i)
    System.out.println((String) lines.elementAt(i));
  }
}

运行:

C:\java>java  HTTPServer
HTTPServer version
Accepted connection to 127.0.0.1 (127.0.0.1) on port 1057.
Received the following request:
GET /index.htm HTTP/1.1
User-Agent: Java/1.4.2_03
Host: 127.0.0.1
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
File sent: C:\java\index.htm
Number of bytes: 47
Request completed. Closing connection.

 

这是客户端部分
import java.io.*;
import java.net.*;
public class Browser 
{
//网址URL
String urlString;
   public static void main(String[] args) throws Exception 
   {
      if(args.length != 1) 
      {
       System.out.println("Usage: Java Browser url");
       System.exit(1);
      }
      Browser browser = new Browser(args[0]);
      browser.run();
   }
   public Browser(String urlString) 
   {
      this.urlString = urlString;
   }
   public void run() throws Exception 
   {
      //生成一个URL对象
      URL url = new URL(urlString);
      //得到输入流
      HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
      //打印头信息
      System.out.println("THE HEADERS");
      System.out.println("-----------");
      for(int i=1;;++i) 
      {
        String key;
        String value;
        if((key = urlc.getHeaderFieldKey(i)) == null) break;
        if((value = urlc.getHeaderField(i)) == null) break;
        System.out.print(key);
        System.out.println(" is: " + value);
      }
      //得到输入流
      BufferedReader reader = new BufferedReader(
      new InputStreamReader(urlc.getInputStream()));
      String line;
      System.out.println("-----CONTENT------");
      while((line = reader.readLine()) != null) System.out.println(line);
   }
}


运行结果:

C:\java>java   Browser  http://127.0.0.1:80/index.htm
THE HEADERS
-----------
Content-Length is: 47
Content-Type is: text/HTML
-----CONTENT------
<html>
<body>
How do you do
</body>
</html>

来源: 不详

阅读(6762) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册