(一)超文本传输协议Http 的操作过程原理
从协议执行的过程来说,浏览器要访问WWW服务时,首先要完成对WWW服务器的域名的解析。一旦获得了IP地址,浏览器通过TCP向服务器请求建立连接。
每一个万维网站点都有一个服务器进程,不断的监听TCP的80端口(默认),当监听到连接请求后,便与浏览器建立连接。TCP连接建立后,浏览器就向服务器发送获取某一web页面的Http请求。服务器收到HTTP请求后,将构建所请求的web页面所必须的信息,并通过HTTP相应返回给浏览器。浏览器再将信息解析,然后将web页面显示给用户,最后,TCP连接释放。
(二)用户单击一个链接后所发生的事件按顺序如下:
1.浏览器分析链接所指向页面的URL(如 http://write.blog.youkuaiyun.com/mdeditor)。
2浏览器像DNS请求解析(write.blog.youkuaiyun.com)的IP地址。
3.域名系统解析出(write.blog.youkuaiyun.com)服务器的IP地址
4.浏览器与该服务器建立TCP链接(默认端口号80)
5.浏览器发出HTTP请求:GET/mdeditor.
6.服务器通过HTTP相应将mdeditor发送给浏览器。
7.TCP释放链接
8浏览器将mdeditor进行解析,并将web页显示给用户
(三)程序功能:
Web 服务器功能为:
(1) Web 服务器可以接受任何 Web 客户的连接
(2) Web 浏览器客户通过地址栏指定服务器地址和请求的页面
(3) Web 服务器对请求进行处理,发送 HTTP 响应
(4) Web 浏览器客户收到 HTTP 响应后显示页面,关闭连接
(四)程序代码
public class webServer {
ServerSocket serverSocket = null;
Socket clientSocket = null;
int counter = 1;
int port = 80 ;
public void WebConnect() throws IOException{
serverSocket = new ServerSocket(port);//创建服务器套接字
System.out.println("Service open....") ;
while(true){
clientSocket = serverSocket.accept();//接受客户机连接,生成套接字
System.out.println("receive "+counter++ +" request" ) ;
Serverdeal() ;
}
}
public void Serverdeal() throws IOException{
final String CRLF = "\r\n";
BufferedReader buf_in = null; //输入流缓冲
DataOutputStream data_out = null; //数据输出流
FileInputStream fileStream=null;//文件输入流
buf_in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//socket输出流
data_out = new DataOutputStream(clientSocket.getOutputStream());
String headstr = buf_in.readLine();//读取浏览器请求头部第一行
File file=returnFileByGet(headstr);//分析HTTP得到要回复的文件
if(file!=null){
/*****输出HTTP头信息*****/
//data_out.writeBytes("HTTP/1.0 200 OK" + CRLF);
if(file.getName().endsWith(".jpg")) {
// data_out.writeBytes("Content-Type: image/jpg" + CRLF);
}
if(file.getName().endsWith(".png")) {
//将字符串按字节顺序写出到基础输出流中
data_out.writeBytes("Content-Type: image/png" + CRLF);
}
data_out.writeBytes(CRLF);
try
{
//获取回复文件的输入流
fileStream=new FileInputStream(file);
} catch (FileNotFoundException e)
{
System.out.println("找不到回复文件");
}
if(file.exists()){
//如果回复文件存在
byte[] buffer = new byte[1024];//缓冲字节数组,也叫缓冲区
int bytes = 0;//读到的字节数
/*发送文件流的实际代码*/
while ((bytes = fileStream.read(buffer)) != -1) {
//不等于-1,就表示还读到内容
//将页面文件,写回给浏览器
data_out.write(buffer, 0, bytes);
}
//完成响应
}
}
if (buf_in != null)buf_in.close();
if (data_out != null)data_out.close();
if (fileStream != null)fileStream.close();
}
public File returnFileByGet(String headstr) {
File file = null ;
StringTokenizer headstrTk=null;
if(headstr!=null){
headstrTk = new StringTokenizer(headstr);//字符串分割
}
//GET命令的格式为:GET 路径/文件名 HTTP/1.1
//只有为get命令才执行下面的代码
if (headstrTk.nextToken().equals("GET"))//判断请求方式
{
String rqFName = headstrTk.nextToken();//分割获取请求的文件名
//如果缺省,返回主页面index.html
if (rqFName.equals("/"))
{
rqFName = "/index.html";
}
//获取请求文件,为不为空都要返回文件
file = new File(rqFName.substring(1));
//显示请求的GET命令格式
System.out.println("request:"+headstr) ; //显示请求
//显示地址和端口
System.out.println("User:"+clientSocket.getInetAddress().toString().substring(1)
+ " 端口:" + String.valueOf(clientSocket.getPort())) ;
if (file.exists())//如果找到文件
{
//if(file.getName().equals(".html")){
System.out.println("Find "+rqFName.substring(1)+" it return!") ;
}
else {//如果没找到请求文件,则返回error.html页面
System.out.println("Not Find "+rqFName.substring(1)+" the Error return!") ;
file = new File("error.html");
}
}
return file ;
}
}
(五)源码下载地址:
(http://download.youkuaiyun.com/download/hdfgo/10189909)