您的位置:首页 > 理论基础 > 计算机网络

java网络编程(三)socket

2013-03-05 14:17 302 查看
socket基础原理不再讲解,这里给出一个例子:socket文件服务器



package com.http.server;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class HttpServer extends Thread{

	private File documentRootDirectory;
	private String indexFileName = "index.html";
	private ServerSocket server;
	private int numThreads = 50;
	
	public HttpServer(File documentRootDirectory,int port,String indexFileName)throws IOException{
		if(!documentRootDirectory.isDirectory()){
			throw new IOException(documentRootDirectory+" does not a directory");
		}
		this.documentRootDirectory = documentRootDirectory;
		this.indexFileName = indexFileName;
		this.server = new ServerSocket(port);
	}
	
	public HttpServer(File documentRootDirectory,int port)throws IOException{
		this(documentRootDirectory,port,"index.html");
	}
	
	public HttpServer(File documentRootDirectory)throws IOException{
		this(documentRootDirectory,80,"index.html");
	}
	
	
	@Override
	public void run() {
		for(int i=0;i<numThreads;i++){
			Thread t = new Thread(new RequestDeal(documentRootDirectory,indexFileName));
			t.start();
		}
		System.out.println("Accepting commections on port "+server.getLocalPort());
		System.out.println("Document Root:"+documentRootDirectory);
		while(true){
			try {
				Socket request = server.accept();
				RequestDeal.processReqeust(request);
			} catch (IOException e) {
			}
			
		}
	}
	
	public static void main(String ...args){
		//得到文档跟
		File docroot;
		try{
			docroot = new File("D:/root");
		}catch(ArrayIndexOutOfBoundsException ex){
			System.out.println("Usage: java JHTTP docroot port indexfile");
			return;
		}
		
		int port;
		try{
			port = Integer.parseInt("80");
		}catch(Exception e){
			port = 80;
		}
		try{
			HttpServer webserver = new HttpServer(docroot,port);
			webserver.start();
		}catch(IOException e){
			System.out.println("Server could not start because of an "+e.getClass());
			System.out.println(e);
		}
	}

	
}


package com.http.server;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

public class RequestDeal implements Runnable {

	private static List<Socket> pool = new LinkedList<Socket>();
	private File documentRootDirectory;
	private String indexFileName = "index.html";
	
	public RequestDeal(File documentRootDirectory,String indexFileName){
		if(documentRootDirectory.isFile()){
			throw new IllegalArgumentException("documentRootDirectory must be a directory,not a file");
		}
		this.documentRootDirectory = documentRootDirectory;
		try {
			this.documentRootDirectory = documentRootDirectory.getCanonicalFile();
		} catch (IOException e) {}
		if(indexFileName!=null)
			this.indexFileName = indexFileName;
	}
	
	public static void processReqeust(Socket request){
		synchronized(pool){
			pool.add(pool.size(),request);
			pool.notifyAll();
		}
	}
	
	@Override
	public void run() {
		//安全性检查
		String root = documentRootDirectory.getPath();
		
		while(true){
			Socket connection=null;
			synchronized(pool){
				while(pool.isEmpty()){
					try {
						pool.wait();
					} catch (InterruptedException e) {}
					
				}
				connection = pool.remove(0);
			}
			
			try{
				String filename;
				String contentType;
				OutputStream raw = new BufferedOutputStream(connection.getOutputStream());
				Writer out = new OutputStreamWriter(raw);
				Reader in = new InputStreamReader(new BufferedInputStream(connection.getInputStream()),"ASCII");
				
				StringBuffer requestLine = new StringBuffer();
				int c;
				while(true){
					c = in.read();
					if(c=='\r' || c=='\n'){
						break;
					}
					requestLine.append((char)c);
				}
				String get = requestLine.toString();
				//记录请求的日志
				System.out.println("log:"+get);
				
				StringTokenizer st = new StringTokenizer(get);
				String method = st.nextToken();
				String version = "";
				if(method.equals("GET")){
					filename = st.nextToken();
					if(filename.endsWith("/")){
						filename +=indexFileName;
					}
					contentType = guessContentTypeFromName(filename);
					if(st.hasMoreTokens()){
						version = st.nextToken();
					}
					
					File theFile = new File(documentRootDirectory,filename.substring(1,filename.length()));
					if(theFile.canRead() && theFile.getCanonicalPath().startsWith(root)){
						//不让请求超出根目录
						DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(theFile)));
						byte [] theData = new byte[(int)theFile.length()];
						fis.readFully(theData);
						fis.close();
						if(version.startsWith("HTTP")){//发送mime首部
							out.write("HTTP/1.1 200 OK\r\n");
							Date now = new Date();
							out.write("Date:"+now+"\r\n");
							out.write("Server: JHTTP/1.0\r\n");
							out.write("Content-length:"+theData.length+"\r\n");
							out.write("Content-type:"+contentType+"\r\n\r\n");
							out.flush();
						}
						//发送文件;可能是图片或者其他二进制数据
						//所以使用底层输出流而不是书写器
						raw.write(theData);
						raw.flush();
					}else{//无法找到文件
						if(version.startsWith("HTTP")){
							out.write("HTTP/1.1 200 File Not Found\r\n");
							Date now = new Date();
							out.write("Date:"+now+"\r\n");
							out.write("Server:JHTTP/1.0\r\n");
							out.write("Content-type:text/html\r\n\r\n");
							out.write("");
						}
						out.write("<HTML>\r\n");
						out.write("<HEAD><TITLE>File Not Found</TITLE>\r\n");
						out.write("</HEAD>\r\n");
						out.write("<BODY>\r\n");
						out.write("<H1>HTTP Error 404:File Not Found</H1>\r\n");
						out.write("</BODY></HTML>\r\n");
						out.flush();
					}
					
				}else{//方法不等于GET
					if(version.startsWith("HTTP")){//发送MIME首部
						out.write("HTTP/1.1 501 Not Implmented\r\n");
						Date now = new Date();
						out.write("Date:"+now+"\r\n");
						out.write("Server:JHTTP 1.0\r\n");
						out.write("Content-type:text/html\r\n\r\n");
					}
					out.write("<HTML>\r\n");
					out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n");
					out.write("</HEAD>\r\n");
					out.write("<BODY>\r\n");
					out.write("<H1>HTTP Error 501 : Not implemented</H1>\r\n");
					out.write("</BODY></HTML>\r\n");
					out.flush();
				}
			}catch(Exception e){
				
			}finally{
				try{
					connection.close();
				}catch(IOException ex){}
			}
		}
	}
	
	public static String guessContentTypeFromName(String name){
		if(name.endsWith(".html") || name.endsWith(".htm")){
			return "text/html";
		}else if(name.endsWith(".txt") || name.endsWith(".java")){
			return "text/plain";
		}else if(name.endsWith(".gif")){
			return "image/gif";
		}else if(name.endsWith(".class")){
			return "application/octet-stream";
		}else if(name.endsWith(".jpg")){
			return "image/jpeg";
		}else{
			return "text/plain";
		}
	}
}


在D盘下创建root目录,然后再root下创建一个文件 a.txt, 格式可以为:.txt .jpg .gif .html .htm,然后运行HttpServer,打开浏览器,输入http://localhost:80/a.txt,回车则可以下载改文件了。

-------------------------------代码来自《java网络编程》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: