英国化学工程专业介绍:增样基于http协议使用Socket写一个web服务器和一个web浏览器

来源:百度文库 编辑:杭州交通信息网 时间:2024/05/04 12:39:06
如果我在Socket套接字的层次上想自己写一个web浏览器,和对应的web服务器大概应该怎么写,比如说,我写一个套接字客户端程序,等他联接到某个web服务器时,客户端应该给他发送什么用的二进制数据,才能获得web服务的返回数据,获得后怎样提取和分离里面的数据,我是说从底层编程的角度考虑,望大侠指点。

最简单的http请求是
GET / HTTP/1.0
其中GET是关键字
/表示请求的是跟目录主页
HTTP/1.0表示使用HTTP协议的1.0版本通讯

作为服务器端,这是会向服务器返回首页的全部html代码

至此,一个最简单的http通讯就完成了。但是,此时网页还不能正常显示,因为服务器仅仅返回了html代码,客户端还必须根据html代码中涉及的其他文件(例如css、js、图象、flash等等)的地址获得相应文件,才能使网页正常显示

下面是http server和client的最简单实现(java)
import java.net.*;
import java.io.*;
import java.util.*;
public class Client
{
public static void main(String[] args)
{
String arg0;
if(args.length!=1)
{
System.out.println("Server name not founud!");
return;
}
else
{
arg0=args[0];
if(arg0.toLowerCase().indexOf("http://")!=0)
arg0="http://"+arg0;
}
try
{
java.net.URL theURL=new java.net.URL(arg0);
java.net.URLConnection conn=theURL.openConnection();
if(conn instanceof java.net.HttpURLConnection)
{
java.net.HttpURLConnection hConn=(HttpURLConnection)conn;
hConn.setFollowRedirects(false);
hConn.connect();
int code=hConn.getResponseCode();
String msg=hConn.getResponseMessage();
if(code==HttpURLConnection.HTTP_OK)
{
System.out.println("Normal response returned:" + code + " " +msg);
java.util.Map headerMap = hConn.getHeaderFields();
java.util.Iterator iterEnt = headerMap.entrySet().iterator();
while(iterEnt.hasNext())
{
System.out.println(iterEnt.next());
}
System.out.println("Hit enter to continue");
System.in.read();
java.io.InputStream in=hConn.getInputStream();
java.io.BufferedInputStream bufIn = new BufferedInputStream(in);
for(;;)
{
int data = bufIn.read();
if(data == -1)
break;
else
System.out.print( (char)data);
}}
else
{
System.out.println("Abormal response returned:" + code + " " +msg);
}}
else
{
System.err.println("Invalid transport protocol: not HTTP!");
return;
}}
catch(java.net.MalformedURLException ex)
{
System.err.println("Unable to parse URL!");
return;
}
catch(java.io.IOException ex)
{
System.err.println("I/O Error: "+ex);
return;
}}}

import java.io.*;
import java.net.*;
import java.util.*;
public class Server
{
protected String docroot;
protected int port;
protected ServerSocket ss;
class Handler extends Thread
{
protected Socket socket;
protected PrintWriter pw;
protected BufferedOutputStream bos;
protected BufferedReader br;
protected File docroot;
public Handler(Socket _socket, String _docroot)throws Exception
{
socket=_socket;
docroot= new File(_docroot).getCanonicalFile() ;
}
public void run()
{
try{
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
bos=new BufferedOutputStream(socket.getOutputStream());
pw=new PrintWriter(new OutputStreamWriter(bos));
String line= br.readLine();
socket.shutdownInput();
if(line==null)
{
socket.close();
return;
}
if(line.toUpperCase().startsWith("GET"))
{
StringTokenizer tokens=new StringTokenizer(line," ?");
tokens.nextToken();
String req = tokens.nextToken() ;
String name;
if(req.startsWith("/") || req.startsWith("\\"))
name=this.docroot + req;
else
name=this.docroot+File.separator+req;
File file=new File(name).getCanonicalFile();
if(!file.getAbsolutePath().startsWith(this.docroot.getAbsolutePath()))
{
pw.println("HTTP/1.0 403 Forbidden");
pw.println();
}
else if(!file.exists())
{
pw.println("HTTP/1.0 404 File Not Found");
pw.println();
}
else if(!file.canRead())
{
pw.println("HTTP/1.0 403 Forbidden");
pw.println();
}
else if(file.isDirectory())
{
sendDir(bos,pw,file,req);
}
else
{
sendFile(bos,pw,file.getAbsolutePath());
}
else
{
pw.println("HTTP/1.0 501 Not Implemented");
pw.println();
}
pw.flush();
bos.flush();
}
catch(Exception ex)
{
ex.printStackTrace();
}
try
{
socket.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
protected void sendFile(BufferedOutputStream bos, PrintWriter pw, String filename) throws Exception
{
try
{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filename));
byte[] data = new byte[10*1024];
int read= bis.read(data);
pw.println("HTTP/1.0 200 Okay");
pw.println();
pw.flush();
bos.flush();
while(read != -1)
{
bos.write(data, 0, read);
read = bis.read(data);
}
bos.flush();
}
catch(Exception ex)
{
pw.flush();
bos.flush();
}
}
protected void sendDir(BufferedOutputStream bos, PrintWriter pw, File dir, String req)throws Exception
{
try
{
pw.println("HTTP/1.0 200 Okay");
pw.println();
pw.flush();
pw.print("<html><head><titleDirectory of ");
pw.print(req);
pw.print("</title></head><body><h1>Directory of ");
pw.print(req);
pw.println("</h1><table border=0>");
File[] contents = dir.listFiles();
for(int i=0; i<contents.length; i++)
{
pw.print("<tr>");
pw.print("<td><a href=\"");
pw.print(req);
pw.print(contents[i].getName());
if(contents[i].isDirectory())
pw.print("/");
pw.print("\">");
if(contents[i].isDirectory())
pw.print("Dir -> ");
pw.print(contents[i].getName());
pw.print("</a></td>");
pw.println("</tr>");
}
pw.println("</table></body></html>");
pw.flush();
}
catch(Exception ex)
{
pw.flush();
bos.flush();
}}}
protected void parseParams(String[] args)
{
switch(args.length)
{
case 1:
case 0:
System.err.println("Syntax: <jvm> "+ this.getClass().getName()+" docroot port");
System.exit(0);
default:
this.docroot= args[0];
this.port = Integer.parseInt(args[1]);
break;
}}
public Server(String[] args)throws Exception
{
System.out.println("Checking for paramaters");
parseParams(args);
System.out.print("Starting web server......");
this.ss = new ServerSocket(this.port);
System.out.println("OK");
for(;;)
{
Socket accept = ss.accept();
new Handler(accept, docroot).start();
}}
public static void main(String[] args)throws Exception
{
Server ser= new Server(args);
}}