java网络编程(三)socket

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");}@Overridepublic 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();}}@Overridepublic 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{//方法不等于GETif(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网络编程》

有时间,我们可以去爬山,

java网络编程(三)socket

相关文章:

你感兴趣的文章:

标签云: