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

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

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

 

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

 

Socket通訊步驟:(簡單分爲4步)服務器

1.創建服務端ServerSocket和客戶端Socket網絡

2.打開鏈接到Socket的輸出輸入流多線程

3.按照協議進行讀寫操做socket

4.關閉相對應的資源this

 

二、相關聯的API:spa

 

1.首先先來看下ServerSocket.net

類 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()
關閉此套接字。

 

三、代碼實現:(註釋很全,這裏就不詳細多說了)

服務端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 }

 

四、效果截圖:

服務端:

客戶端:

 

 

以上代碼實現了單客戶端和服務端的鏈接,若要實現多客戶端操做,須要涉及到多線程,只要你把每一個接收到的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/本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,往後必有一番做爲!旁邊有「推薦」二字,你就順手把它點了吧,相得準,我分文不收;相不許,你也好回來找我!

相關文章
相關標籤/搜索