最近再學習java的web編程,發現用java建立一個小的服務器和客戶端是如此的簡單,引用經典圖書《Tomcat與Java Web開發技術詳解(第二版)》(孫衛琴)html
根據書中案例敲代碼本身學習,放這裏記錄一下,以便複習:)java
服務器端程序,接收客戶端程序發出的HTTP請求,把它打印到控制檯,而後解析HTTP請求,並向客戶端發回相應的HTTP響應。web
HTTPServer類中service()方法中,先讀取HTTP請求數據,而後得到HTTP請求中的URL,隨後建立一個讀取本地文件的輸入流,該文件的路徑由URI決定編程
HTTPServer.java:瀏覽器
package server;
import java.io.*;
import java.net.*;
public class HTTPServer {
public static void main(String args[]) {
int port;
ServerSocket serverSocket;
try {
port = Integer.parseInt(args[0]);
}catch (Exception e) {
System.out.println("port = 8080 (默認)");
port = 8080;
}
try {
serverSocket = new ServerSocket(port);
System.out.println("服務器正在監聽端口:"+serverSocket.getLocalPort());
while(true) {
try {
//等待客戶端的TCP鏈接請求
final Socket socket = serverSocket.accept();
System.out.println("創建了與客戶的一個新的TCP鏈接,該客戶的地址爲:"
+socket.getInetAddress()+":"+socket.getPort());
service(socket);
} catch(Exception e) {e.printStackTrace();}
} //#while
} catch(Exception e) {e.printStackTrace();}
}
/*響應客戶的HTTP請求*/
public static void service(Socket socket) throws Exception {
/*讀取HTTP請求信息*/
InputStream socketIn = socket.getInputStream(); //得到輸入流
Thread.sleep(500); //睡眠500毫秒,等待HTTP請求
int size = socketIn.available();
byte[] buffer = new byte[size];
socketIn.read(buffer);
String request = new String(buffer);
System.out.println("http請求數據: \n"+request); //打印HTTP請求數據
/*解析HTTP請求*/
//得到HTTP請求的第一行
String firstLineOfRequest=request.substring(0,request.indexOf("\r\n"));
//解析HTTP請求的第一行
String[] parts = firstLineOfRequest.split(" ");
String uri = parts[1]; //得到HTTP請求中的uri
/*決定HTTP響應正文的類型,此處作了簡化處理*/
String contentType;
if(uri.indexOf("html")!= -1 || uri.indexOf("htm") != -1)
contentType = "text/html";
else if(uri.indexOf("jpg")!= -1 || uri.indexOf("jpeg")!= -1)
contentType = "image/jpeg";
else if(uri.indexOf("gif")!= -1)
contentType = "image/gif";
else
contentType = "application/octet-stream"; //字節流類型
/*建立HTTP響應結果*/
//HTTP響應的第一行
String responseFirstLine = "HTTP/1.1 200 OK\r\n";
//HTTP響應頭
String responseHeader = "Content-Type:"+contentType+"\r\n\r\n";
//得到讀取響應正文數據的數據流
InputStream in = HTTPServer.class.getResourceAsStream("root/"+uri);
/*發送HTTP響應結果*/
OutputStream socketOut = socket.getOutputStream(); //獲取數據流
//發送HTTP響應的第一行
socketOut.write(responseFirstLine.getBytes());
//發送HTTP響應頭
socketOut.write(responseHeader.getBytes());
//發送HTTP響應的正文
int len=0;
buffer = new byte[128];
while((len=in.read(buffer))!=-1)
socketOut.write(buffer,0,len);
Thread.sleep(1000); //睡眠1秒,等待客戶端接受HTTP響應結果
socket.close(); //關閉TCP鏈接
}
}
服務器
客戶端程序,以GET方式向HTTP服務器發送HTTP請求,而後把接收到的HTTP響應結果打印到控制檯,並無進行解析app
HTTPClient.javasocket
package client;
import java.io.*;
import java.net.*;
import java.util.*;
public class HTTPClient {
public static void main(String args[]) {
//肯定HTTP請求的uri
String uri = "Welcome.html";
if(args.length !=0)
uri=args[0];
doGet("localhost",8080,uri); //按照GET請求方式訪問HTTPServer
}
/**按照GET請求方式訪問HTTPServer */
private static void doGet(String host, int port, String uri) {
// TODO Auto-generated method stub
Socket socket = null;
try{
socket = new Socket(host,port); //與HTTPServer創建TCP鏈接
}catch (Exception e){e.printStackTrace();}
try{
/*建立HTTP請求*/
StringBuffer sb = new StringBuffer("GET "+uri+" HTTP/1.1\r\n"); //HTTP請求的第一行
//HTTP請求頭
sb.append("Accept: */*\r\n");
sb.append("Accept-Language: zh-cn\r\n");
sb.append("Accept-Encoding: gzip, deflate\r\n");
sb.append("User-Agent: HTTPClient\r\n");
sb.append("Host: localhost:8080\r\n");
sb.append("Connection: Keep-Alive\r\n\r\n");
/*發送HTTP請求*/
OutputStream socketOut = socket.getOutputStream(); //得到輸出流
socketOut.write(sb.toString().getBytes());
Thread.sleep(2000); //睡眠2秒,等待響應結果
/*接受響應結果*/
InputStream socketIn = socket.getInputStream();
int size = socketIn.available();
byte[] buffer = new byte[size];
socketIn.read(buffer);
System.out.println(new String(buffer)); //打印響應結果
}catch(Exception e){
e.printStackTrace();
}finally{
try{
socket.close();
}catch(Exception e){e.printStackTrace();}
}
}
}學習
客戶端參數&服務端本地文件Hello1.html:.net
<html>
<head>
<title>
HelloWorld!
</title>
</head>
<body>
<h1>Hello</h1>
<img src="xiongbenxiong.gif" align="middle"/>
</body>
</html>
運行結果:
瀏覽器顯示: