基於Tcp協議的簡單Socket通信實例(JAVA)


好久沒寫博客了,前段時間忙於做項目,耽誤了些時間,今天開始繼續寫起~

今天來講下關於Socket通信的簡單應用,關於什么是Socket以及一些網絡編程的基礎,這里就不提了,只記錄最簡單易懂實用的東西。

 

1、首先先來看下基於TCP協議Socket服務端和客戶端的通信模型:

 

Socket通信步驟:(簡單分為4步)

1.建立服務端ServerSocket和客戶端Socket

2.打開連接到Socket的輸出輸入流

3.按照協議進行讀寫操作

4.關閉相對應的資源

 

2、相關聯的API:

 

1.首先先來看下ServerSocket

類 ServerSocket 

此類實現服務器套接字。服務器套接字等待請求通過網絡傳入。它基於該請求執行某些操作,然后可能向請求者返回結果。

服務器套接字的實際工作由 SocketImpl 類的實例執行。應用程序可以更改創建套接字實現的套接字工廠來配置它自身,從而創建適合本地防火牆的套接字。 

一些重要的方法:(具體大家查看官方api吧)

ServerSocket(int port, int backlog)
利用指定的 backlog 創建服務器套接字並將其綁定到指定的本地端口號。

bind(SocketAddress endpoint, int backlog)
ServerSocket 綁定到特定地址(IP 地址和端口號)。

accept()
偵聽並接受到此套接字的連接

getInetAddress()
返回此服務器套接字的本地地址。

 close()
關閉此套接字。

 

2.再來看下Socket

類 Socket  

此類實現客戶端套接字(也可以就叫“套接字”)。套接字是兩台機器間通信的端點。

套接字的實際工作由 SocketImpl 類的實例執行。應用程序通過更改創建套接字實現的套接字工廠可以配置它自身,以創建適合本地防火牆的套接字。

一些重要的方法:(具體大家查看官方api吧)

Socket(InetAddress address, int port)
創建一個流套接字並將其連接到指定 IP 地址的指定端口號。

getInetAddress()
返回套接字連接的地址。

shutdownInput()
此套接字的輸入流置於“流的末尾”。

shutdownOutput()
禁用此套接字的輸出流。

close()
關閉此套接字。

 

3、代碼實現:(注釋很全,這里就不詳細多說了)

服務端Server.java

1.創建ServerSocket對象,綁定並監聽端口

2.通過accept監聽客戶端的請求

3.建立連接后,通過輸出輸入流進行讀寫操作

4.關閉相關資源

 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 public class Server {
12 
13     /**
14      * Socket服務端
15      */
16     public static void main(String[] args) {
17         try {
18             ServerSocket serverSocket=new ServerSocket(8888);
19             System.out.println("服務端已啟動,等待客戶端連接..");
20             Socket socket=serverSocket.accept();//偵聽並接受到此套接字的連接,返回一個Socket對象
21             
22             
23             //根據輸入輸出流和客戶端連接
24             InputStream inputStream=socket.getInputStream();//得到一個輸入流,接收客戶端傳遞的信息
25             InputStreamReader inputStreamReader=new InputStreamReader(inputStream);//提高效率,將自己字節流轉為字符流
26             BufferedReader bufferedReader=new BufferedReader(inputStreamReader);//加入緩沖區
27             String temp=null;
28             String info="";
29             while((temp=bufferedReader.readLine())!=null){
30                 info+=temp;
31                 System.out.println("已接收到客戶端連接");
32                 System.out.println("服務端接收到客戶端信息:"+info+",當前客戶端ip為:"+socket.getInetAddress().getHostAddress());
33             }
34             
35             OutputStream outputStream=socket.getOutputStream();//獲取一個輸出流,向服務端發送信息
36             PrintWriter printWriter=new PrintWriter(outputStream);//將輸出流包裝成打印流
37             printWriter.print("你好,服務端已接收到您的信息");
38             printWriter.flush();
39             socket.shutdownOutput();//關閉輸出流
40             
41             
42             
43             //關閉相對應的資源
44             printWriter.close();
45             outputStream.close();
46             bufferedReader.close();
47             inputStream.close();
48             socket.close();
49             
50         } catch (IOException e) {
51             e.printStackTrace();
52         }
53     }
54 
55 }

 

客戶端Client.java

1.創建Socket對象,指定服務端的地址和端口號

2.建立連接后,通過輸出輸入流進行讀寫操作

3.通過輸出輸入流獲取服務器返回信息

4.關閉相關資源

 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 public class Client {
12 
13     /**
14      * Socket客戶端
15      */
16     public static void main(String[] args) {
17         try {
18             //創建Socket對象
19             Socket socket=new Socket("localhost",8888);
20             
21             //根據輸入輸出流和服務端連接
22             OutputStream outputStream=socket.getOutputStream();//獲取一個輸出流,向服務端發送信息
23             PrintWriter printWriter=new PrintWriter(outputStream);//將輸出流包裝成打印流
24             printWriter.print("服務端你好,我是Balla_兔子");
25             printWriter.flush();
26             socket.shutdownOutput();//關閉輸出流
27             
28             InputStream inputStream=socket.getInputStream();//獲取一個輸入流,接收服務端的信息
29             InputStreamReader inputStreamReader=new InputStreamReader(inputStream);//包裝成字符流,提高效率
30             BufferedReader bufferedReader=new BufferedReader(inputStreamReader);//緩沖區
31             String info="";
32             String temp=null;//臨時變量
33             while((temp=bufferedReader.readLine())!=null){
34                 info+=temp;
35                 System.out.println("客戶端接收服務端發送信息:"+info);
36             }
37             
38             //關閉相對應的資源
39             bufferedReader.close();
40             inputStream.close();
41             printWriter.close();
42             outputStream.close();
43             socket.close();
44         } catch (UnknownHostException e) {
45             e.printStackTrace();
46         } catch (IOException e) {
47             e.printStackTrace();
48         }
49 
50     }
51 
52 }

 

4、效果截圖:

服務端:

客戶端:

 

 

以上代碼實現了單客戶端和服務端的連接,若要實現多客戶端操作,需要涉及到多線程,只要你把每個接收到的Socket對象單獨開一條線程操作,然后用一個死循環while(true)去監聽端口就行,這邊直接給代碼了

 

線程操作類:SocketThread.java

 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  * Socket多線程處理類 用來處理服務端接收到的客戶端請求(處理Socket對象)
11  */
12 public class SocketThread extends Thread {
13     private Socket socket;
14 
15     public SocketThread(Socket socket) {
16         this.socket = socket;
17     }
18 
19     public void run() {
20         // 根據輸入輸出流和客戶端連接
21         try {
22             InputStream inputStream = socket.getInputStream();
23             // 得到一個輸入流,接收客戶端傳遞的信息
24             InputStreamReader inputStreamReader = new InputStreamReader(
25                     inputStream);// 提高效率,將自己字節流轉為字符流
26             BufferedReader bufferedReader = new BufferedReader(
27                     inputStreamReader);// 加入緩沖區
28             String temp = null;
29             String info = "";
30             while ((temp = bufferedReader.readLine()) != null) {
31                 info += temp;
32                 System.out.println("已接收到客戶端連接");
33                 System.out.println("服務端接收到客戶端信息:" + info + ",當前客戶端ip為:"
34                         + socket.getInetAddress().getHostAddress());
35             }
36 
37             OutputStream outputStream = socket.getOutputStream();// 獲取一個輸出流,向服務端發送信息
38             PrintWriter printWriter = new PrintWriter(outputStream);// 將輸出流包裝成打印流
39             printWriter.print("你好,服務端已接收到您的信息");
40             printWriter.flush();
41             socket.shutdownOutput();// 關閉輸出流
42 
43             // 關閉相對應的資源
44             bufferedReader.close();
45             inputStream.close();
46             printWriter.close();
47             outputStream.close();
48         } catch (IOException e) {
49             e.printStackTrace();
50         }
51 
52     }
53 
54 }

 

服務端類:Server.java

 1 import java.io.IOException;
 2 import java.net.ServerSocket;
 3 import java.net.Socket;
 4 
 5 public class Server {
 6 
 7     /**
 8      * Socket服務端
 9      */
10     public static void main(String[] args) {
11         try {
12             ServerSocket serverSocket = new ServerSocket(8888);
13             System.out.println("服務端已啟動,等待客戶端連接..");
14 
15             while (true) {
16                 Socket socket = serverSocket.accept();// 偵聽並接受到此套接字的連接,返回一個Socket對象
17                 SocketThread socketThread = new SocketThread(socket);
18                 socketThread.start();
19             }
20 
21         } catch (IOException e) {
22             e.printStackTrace();
23         }
24     }
25 
26 }

 

客戶端類:Client.java

 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 public class Client {
12 
13     /**
14      * Socket客戶端
15      */
16     public static void main(String[] args) {
17         try {
18             //創建Socket對象
19             Socket socket=new Socket("localhost",8888);
20             
21             //根據輸入輸出流和服務端連接
22             OutputStream outputStream=socket.getOutputStream();//獲取一個輸出流,向服務端發送信息
23             PrintWriter printWriter=new PrintWriter(outputStream);//將輸出流包裝成打印流
24             printWriter.print("服務端你好,我是客戶1");
25             printWriter.flush();
26             socket.shutdownOutput();//關閉輸出流
27             
28             InputStream inputStream=socket.getInputStream();//獲取一個輸入流,接收服務端的信息
29             InputStreamReader inputStreamReader=new InputStreamReader(inputStream);//包裝成字符流,提高效率
30             BufferedReader bufferedReader=new BufferedReader(inputStreamReader);//緩沖區
31             String info="";
32             String temp=null;//臨時變量
33             while((temp=bufferedReader.readLine())!=null){
34                 info+=temp;
35                 System.out.println("客戶端接收服務端發送信息:"+info);
36             }
37             
38             //關閉相對應的資源
39             bufferedReader.close();
40             inputStream.close();
41             printWriter.close();
42             outputStream.close();
43             socket.close();
44         } catch (UnknownHostException e) {
45             e.printStackTrace();
46         } catch (IOException e) {
47             e.printStackTrace();
48         }
49 
50     }
51 
52 }

 

看下效果實現圖:

 

這里只是拋磚引玉,在實際開發中,基於Socket編程,一般傳遞的並非字符串,很多情況下是對象,我們可以使用ObjectOutputStream將輸出流對象序列化。

例如:

1             OutputStream outputStream = socket.getOutputStream();
2             ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
3             User user=new User("admin","123456");
4             objectOutputStream.writeObject(user);

 

作者:Balla_兔子
出處:http://www.cnblogs.com/lichenwei/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日后必有一番作為!旁邊有“推薦”二字,你就順手把它點了吧,相得准,我分文不收;相不准,你也好回來找我!


免責聲明!

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



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