一、Socket簡介
Socket通信實現步驟
1.創建ServerSocket和Socket
2.打開連接到Socket的輸入/輸出流
3.按照協議對Socket進行讀/寫操作
4.關閉輸入輸出流、關閉Socket
二、編程實現基於TCP的Socket通信之服務端與客戶端
服務器端:
1.創建ServerSocket對象,綁定監聽端口
2.通過accept()方法監聽客戶端請求
3.連接建立后,通過輸入流讀取客戶端發送的請求信息
4.通過輸出流向客戶端響應信息
5.關閉相關資源
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 8 /* 9 * 基於TCP協議的Socket通信,實現用戶登陸 10 * 服務器端 11 */ 12 public class Server { 13 public static void main(String[] args) { 14 try { 15 //1.創建一個服務器端Socket,即ServerSocket,指定綁定的端口,並監聽此端口 16 ServerSocket serverSocket = new ServerSocket(8888); 17 //2.調用accept()方法開始監聽,等待客戶端的連接 18 System.out.println("***服務器即將啟動,等待客戶端的連接***"); 19 Socket socket = serverSocket.accept(); 20 //3.獲取輸入流,並讀取客戶端信息 21 InputStream is = socket.getInputStream();//字節輸入流 22 InputStreamReader isr = new InputStreamReader(is);//將字節流轉換為字符流 23 BufferedReader br = new BufferedReader(isr);//為輸入流添加緩沖 24 String info = null; 25 while((info=br.readLine())!=null) {//循環讀取客戶端的信息 26 System.out.println("我是服務器,客戶端說:" + info); 27 } 28 socket.shutdownInput();//關閉輸入流 29 30 //4.關閉資源 31 br.close(); 32 isr.close(); 33 is.close(); 34 socket.close(); 35 serverSocket.close(); 36 } catch (IOException e) { 37 // TODO Auto-generated catch block 38 e.printStackTrace(); 39 } 40 41 } 42 43 }
客戶端:
1.創建Socket對象,指明需要連接的服務器的地址和端口號
2.連接建立后,通過輸出流向服務器發送請求信息
3.通過輸入流獲取服務器響應的信息
4.關閉相應資源
1 import java.io.IOException; 2 import java.io.OutputStream; 3 import java.io.PrintWriter; 4 import java.net.Socket; 5 import java.net.UnknownHostException; 6 7 /* 8 * 客戶端 9 */ 10 public class Client { 11 public static void main(String[] args) { 12 try { 13 //1.創建客戶端Socket,指定服務器地址和端口 14 Socket socket = new Socket("localhost",8888); 15 //2.獲取輸出流,向服務器端發送信息 16 OutputStream os = socket.getOutputStream();//字節輸出流 17 PrintWriter pw = new PrintWriter(os); 18 pw.write("用戶名:admin;密碼:123"); 19 pw.flush(); 20 socket.shutdownOutput();//關閉輸出流 21 22 //3.關閉資源 23 pw.close(); 24 os.close(); 25 socket.close(); 26 } catch (UnknownHostException e) { 27 e.printStackTrace(); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 }
三、完善用戶登陸之服務器響應客戶端
服務端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 10 /* 11 * 基於TCP協議的Socket通信,實現用戶登陸 12 * 服務器端(需要早於客戶端啟動) 13 */ 14 public class Server { 15 public static void main(String[] args) { 16 try { 17 //1.創建一個服務器端Socket,即ServerSocket,指定綁定的端口,並監聽此端口 18 ServerSocket serverSocket = new ServerSocket(8888); 19 //2.調用accept()方法開始監聽,等待客戶端的連接 20 System.out.println("***服務器即將啟動,等待客戶端的連接***"); 21 Socket socket = serverSocket.accept(); 22 //3.獲取輸入流,並讀取客戶端信息 23 InputStream is = socket.getInputStream();//字節輸入流 24 InputStreamReader isr = new InputStreamReader(is);//將字節流轉換為字符流 25 BufferedReader br = new BufferedReader(isr);//為輸入流添加緩沖 26 String info = null; 27 while((info=br.readLine())!=null) {//循環讀取客戶端的信息 28 System.out.println("我是服務器,客戶端說:" + info); 29 } 30 socket.shutdownInput();//關閉輸入流 31 32 //4.獲取輸出流,響應客戶端的請求 33 OutputStream os = socket.getOutputStream(); 34 PrintWriter pw = new PrintWriter(os);//包裝為打印流 35 pw.write("歡迎您!"); 36 pw.flush();//調用flush()方法將緩沖輸出 37 38 //5.關閉資源 39 pw.close(); 40 os.close(); 41 br.close(); 42 isr.close(); 43 is.close(); 44 socket.close(); 45 serverSocket.close(); 46 } catch (IOException e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 51 } 52 53 }
客戶端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 10 /* 11 * 基於TCP協議的Socket通信,實現用戶登陸 12 * 服務器端(需要早於客戶端啟動) 13 */ 14 public class Server { 15 public static void main(String[] args) { 16 try { 17 //1.創建一個服務器端Socket,即ServerSocket,指定綁定的端口,並監聽此端口 18 ServerSocket serverSocket = new ServerSocket(8888); 19 //2.調用accept()方法開始監聽,等待客戶端的連接 20 System.out.println("***服務器即將啟動,等待客戶端的連接***"); 21 Socket socket = serverSocket.accept(); 22 //3.獲取輸入流,並讀取客戶端信息 23 InputStream is = socket.getInputStream();//字節輸入流 24 InputStreamReader isr = new InputStreamReader(is);//將字節流轉換為字符流 25 BufferedReader br = new BufferedReader(isr);//為輸入流添加緩沖 26 String info = null; 27 while((info=br.readLine())!=null) {//循環讀取客戶端的信息 28 System.out.println("我是服務器,客戶端說:" + info); 29 } 30 socket.shutdownInput();//關閉輸入流 31 32 //4.獲取輸出流,響應客戶端的請求 33 OutputStream os = socket.getOutputStream(); 34 PrintWriter pw = new PrintWriter(os);//包裝為打印流 35 pw.write("歡迎您!"); 36 pw.flush();//調用flush()方法將緩沖輸出 37 38 //5.關閉資源 39 pw.close(); 40 os.close(); 41 br.close(); 42 isr.close(); 43 is.close(); 44 socket.close(); 45 serverSocket.close(); 46 } catch (IOException e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 51 } 52 53 }
四、使用多線程實現多客戶端的通信
應用多線程來實現服務器與多客戶端之間的通信
基本步驟:
1.服務器端創建ServerSocket,循環調用accept()等待客戶端連接
2.客戶端創建一個socket並請求和服務器端連接
3.服務器端接受客戶端請求,創建socket與該客戶建立專線連接
4.建立連接的兩個socket在一個單獨的線程上對話
5.服務器端繼續等待新的連接
服務器線程處理類:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.Socket; 8 9 /* 10 * 服務器線程處理類 11 */ 12 public class ServerThread extends Thread { 13 // 和本線程相關的Socket 14 Socket socket = null; 15 16 public ServerThread(Socket socket) { 17 this.socket = socket; 18 } 19 20 //線程執行的操作,響應客戶端的請求 21 public void run(){ 22 InputStream is=null; 23 InputStreamReader isr=null; 24 BufferedReader br=null; 25 OutputStream os=null; 26 PrintWriter pw=null; 27 try { 28 //獲取輸入流,並讀取客戶端信息 29 is = socket.getInputStream(); 30 isr = new InputStreamReader(is); 31 br = new BufferedReader(isr); 32 String info=null; 33 while((info=br.readLine())!=null){//循環讀取客戶端的信息 34 System.out.println("我是服務器,客戶端說:"+info); 35 } 36 socket.shutdownInput();//關閉輸入流 37 //獲取輸出流,響應客戶端的請求 38 os = socket.getOutputStream(); 39 pw = new PrintWriter(os); 40 pw.write("歡迎您!"); 41 pw.flush();//調用flush()方法將緩沖輸出 42 } catch (IOException e) { 43 e.printStackTrace(); 44 }finally{ 45 //關閉資源 46 try { 47 if(pw!=null) 48 pw.close(); 49 if(os!=null) 50 os.close(); 51 if(br!=null) 52 br.close(); 53 if(isr!=null) 54 isr.close(); 55 if(is!=null) 56 is.close(); 57 if(socket!=null) 58 socket.close(); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 } 62 } 63 } 64 }
修改服務器端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.InetAddress; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 11 /* 12 * 基於TCP協議的Socket通信,實現用戶登陸 13 * 服務器端(需要早於客戶端啟動) 14 */ 15 public class Server { 16 public static void main(String[] args) { 17 try { 18 //1.創建一個服務器端Socket,即ServerSocket,指定綁定的端口,並監聽此端口 19 ServerSocket serverSocket = new ServerSocket(8888); 20 21 Socket socket = null; 22 //記錄客戶端的數量 23 int count = 0; 24 System.out.println("***服務器即將啟動,等待客戶端的連接***"); 25 //循環監聽等待客戶端的連接 26 while (true) { 27 //2.調用accept()方法開始監聽,等待客戶端的連接 28 socket = serverSocket.accept(); 29 //創建一個新的線程 30 ServerThread serverThread = new ServerThread(socket); 31 //啟動線程 32 serverThread.start(); 33 34 count++;//統計客戶端的數量 35 System.out.println("輸出客戶端的數量:" + count); 36 InetAddress address = socket.getInetAddress(); 37 System.out.println("當前客戶端的IP:" + address.getHostAddress()); 38 } 39 40 41 42 43 /* 44 //3.獲取輸入流,並讀取客戶端信息 45 InputStream is = socket.getInputStream();//字節輸入流 46 InputStreamReader isr = new InputStreamReader(is);//將字節流轉換為字符流 47 BufferedReader br = new BufferedReader(isr);//為輸入流添加緩沖 48 String info = null; 49 while((info=br.readLine())!=null) {//循環讀取客戶端的信息 50 System.out.println("我是服務器,客戶端說:" + info); 51 } 52 socket.shutdownInput();//關閉輸入流 53 54 //4.獲取輸出流,響應客戶端的請求 55 OutputStream os = socket.getOutputStream(); 56 PrintWriter pw = new PrintWriter(os);//包裝為打印流 57 pw.write("歡迎您!"); 58 pw.flush();//調用flush()方法將緩沖輸出 59 60 //5.關閉資源 61 pw.close(); 62 os.close(); 63 br.close(); 64 isr.close(); 65 is.close(); 66 socket.close(); 67 */ 68 69 70 //serverSocket.close(); 71 72 } catch (IOException e) { 73 // TODO Auto-generated catch block 74 e.printStackTrace(); 75 } 76 77 } 78 79 }
修改客戶端:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.io.PrintWriter; 7 import java.net.Socket; 8 import java.net.UnknownHostException; 9 10 /* 11 * 客戶端 12 */ 13 public class Client { 14 public static void main(String[] args) { 15 try { 16 //1.創建客戶端Socket,指定服務器地址和端口 17 Socket socket = new Socket("localhost",8888); 18 //2.獲取輸出流,向服務器端發送信息 19 OutputStream os = socket.getOutputStream();//字節輸出流 20 PrintWriter pw = new PrintWriter(os); 21 pw.write("用戶名:admin;密碼:123"); 22 pw.flush(); 23 socket.shutdownOutput();//關閉輸出流 24 25 //3.獲取輸入流,並讀取服務器端的響應信息 26 InputStream is = socket.getInputStream();//字節輸入流 27 BufferedReader br = new BufferedReader( 28 new InputStreamReader(is));//將字節流轉換為字符流,為輸入流添加緩沖 29 String info = null; 30 while((info=br.readLine())!=null) {//循環讀取客戶端的信息 31 System.out.println("我是客戶端,服務器說:" + info); 32 } 33 34 //4.關閉資源 35 br.close(); 36 is.close(); 37 pw.close(); 38 os.close(); 39 socket.close(); 40 } catch (UnknownHostException e) { 41 e.printStackTrace(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 } 45 } 46 }