通過 Socket 實現 TCP 編程


一、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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM