import java.io.*; import java.net.*; //包含StringTokennizer类,可以解析HTTP请求报文 import java.util.*; public class SimpleServer { public static void main(String[] args)throws Exception { /*该字符串将包含请求报文的第一行,即请求行*/ String requestMessageLine; //包含所请求的文件名 String fileName; ServerSocket listensocket = new ServerSocket(6789); Socket connectionSocket = listensocket.accept(); //存储所接收的请求报文 BufferedReader inFormClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); //存储响应报文 DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); //读取请求报文的第一行 requestMessageLine =inFormClient.readLine(); //准备解析请求行,以获得所请求的文件名 StringTokenizer tokenizerdLine=new StringTokenizer(requestMessageLine); if(tokenizerdLine.nextToken().equals("GET")){ fileName=tokenizerdLine.nextToken(); //去除文件名可能出现的斜线 if (fileName.startsWith("/")){ fileName=fileName.substring(1); } File file=new File(fileName); int numbOfBytes=(int)file.length(); //将inFile流连接到fileName文件 FileInputStream inFile=new FileInputStream(fileName); //下面的指令确定了文件的长度,构造了相应大小的字节数组,数组名为fileInBytes byte[] fileInBytes=new byte[numbOfBytes]; //从inFile流中读取数据并存放到fileInBytes中 //程序必须将其转换为字节,因为输出流outToClient仅能按字节输入 inFile.read(fileInBytes); //现在开始构建HTTP响应报文 //为此,首先需要将HTTP响应报文状态行发送到DataOutputStream outToClient流中 outToClient.writeBytes("HTTP/1.0 200 Document Folllows\r\n"); //接下来的代码为HTTP响应报文准备了首部行,并将首部行发送到TCP缓冲发送缓冲 if (fileName.endsWith(".jpg")){ outToClient.writeBytes("Content-Type:image/jpeg\r\n"); } if(fileName.endsWith(".gif")){ outToClient.writeBytes("Content-Type:image/gif\r\n"); } //描述文件长度 outToClient.writeBytes("Content-Length:"+numbOfBytes+"\r\n"); //强制性空行 outToClient.writeBytes("\r\n"); //发送所请求的文件fileInBytes,发送到TCP发送缓冲 //如果有必要,会将文件分段 outToClient.write(fileInBytes,0,numbOfBytes); //处理完一个文件请求后,服务器关闭套接字 connectionSocket.close(); } else System.out.println("Bad Request Message"); } }