做web开发有一段时间了,但对于HTTP协议却没有深入的理解学习过。做了一小小的测试终于彻底明白了HTTP协议。自己的服务器上已经安装了Apache服务并且已经启动。Apache服务监听在80端口。
- import java.io.*;
- import java.net.*;
- public class HttpRequest
- {
- public static void main(String []args)throws Exception{
- //连接到服务器
- Socket socket = new Socket("localhost",80);
- OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
- StringBuffer sb = new StringBuffer();
- sb.append("GET / HTTP/1.1\r\n");
- sb.append("Host:localhost\r\n");
- sb.append("Accept-Language:zh-cn\r\n");
- //请求头结束
- sb.append("\r\n");
- out.write(sb.toString());
- out.flush();
- InputStreamReader buf = new InputStreamReader(socket.getInputStream());
- String str="";
- int num = 0;
- FileOutputStream output = new FileOutputStream(new File("D:\\menu.html"));
- str = getSockLine(buf);
- /** 解析出响应头部的所有字段 */
- while(!str.equals("\r\n")){
- if(str.contains("Content-Length:"))
- {
- //解析出响应头部后真实的数据长度
- num = Integer.parseInt(str.substring(15).trim());
- }
- str = getSockLine(buf);
- }
- char bytes[] = new char[1024];
- int nread = 0;
- while(num > 0)
- {
- //Content-Length:字段是字节数长度。考虑汉字情况,如果直接用str.length处理。有可能会进入到死循环
- nread = buf.read(bytes, 0, 1024);
- String temp = new String(bytes,0,nread);
- output.write(temp.getBytes());
- //output.write(b, off, len)
- //获取字符串字节长度
- int len = temp.getBytes().length;
- num -= len;
- if(num<=0)break;
- }
- output.flush();
- output.close();
- buf.close();
- socket.close();
- }
- private static String getSockLine(InputStreamReader buf) throws IOException
- {
- StringBuffer sb = new StringBuffer("");
- int n;
- while( (n=buf.read()) != -1)
- {
- sb.append((char)n);
- if( ((char)n) =='\r')
- {
- n = buf.read();
- if(((char)n)=='\n')
- {
- sb.append('\n');
- break;
- }
- }
- }
- return sb.toString();
- }
- }
返回的内容是一html文件(也就是我们平时查看源码时看到的玩意)。浏览器会解析各个标签和样式,再把解析的结果输出的屏幕上。这就是我们看到的页面效果。