1. 程式人生 > >實現socket的服務和客戶端通訊

實現socket的服務和客戶端通訊

對學習過程中自己敲的一些關於socket有關的程式碼做了個簡單總結,在這分享一下,給有需要的同學借鑑一下。

什麼是socket?

網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。 建立網路通訊連線至少要一對埠號(socket)。socket本質是程式設計介面(API),對TCP/IP的封裝,TCP/IP也要提供可供程式設計師做網路開發所用的介面,這就是Socket程式設計介面;HTTP是轎車,提供了封裝或者顯示資料的具體形式;Socket是發動機,提供了網路通訊的能力。 Socket的英文原義是“孔”或“插座”。作為BSD UNIX的程序通訊機制,取後一種意思。通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的控制代碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。Socket正如其英文原義那樣,像一個多孔插座。一臺主機猶如佈滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。 Java就給我們提供了socket,我們只要會使用就可以了,接下來為大家介紹一個簡單的socket小例子,完成socket服務和客戶端間的通訊。 這是我們socket小例子的一個簡單架構,由服務端、客戶端、執行緒工作業務邏輯、資料獲取類組成。

 

首先我們先來完成socket服務端的程式碼開發。

在服務端的main方法裡,我們將socketserver物件設定成持久的,並綁定於本機的8899埠上,去接收客戶端的socket連線。

package com.wenbing.socket;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;

public class ServiceServer {

    public
static void main(String[] args) throws Exception{ // 建立一個serversocket,繫結到本機的8899埠上 ServerSocket server = new ServerSocket(); server.bind(new InetSocketAddress("localhost", 8899)); // 接收客戶端的連線;accept是一個阻塞方法,會一直等待,到有客戶端請求連線才返回 while (true) { Socket socket
= server.accept(); // 每個socket請求都給一個執行緒來處理 new Thread(new ServiceServerTask(socket)).start(); } } }

 

 我們定義一個服務端處理客戶端請求過來的資料處理執行緒工作類,讓每個請求來的socket都由每一個執行緒去執行業務邏輯,ServiceServerTask類實行Runnable介面。
package com.wenbing.socket;

import java.io.*;
import java.net.Socket;

public class ServiceServerTask implements Runnable {

    Socket socket;
    InputStream inputStream = null;
    OutputStream outputStream = null;

    public ServiceServerTask(Socket socket) {
        this.socket = socket;
    }

    //    業務邏輯,跟客戶端進行資料互動
    @Override
    public void run() {

        try {
//            從socket連線中獲取到與client之間的網路通訊輸入流
            inputStream = socket.getInputStream();
//            從socket連線中獲取到與client之間的網路通訊輸出流
            outputStream = socket.getOutputStream();

//            BufferedReader讀取資料是一個字元一個字元讀取,遇到回車即停止
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
//            從網路通訊輸入流中讀取客戶端傳送過來的資料,讀取一行,遇到回車即結束
            // 注意:socketinputstream的讀資料的方法是阻塞的
            //讀取很多行資料,用while迴圈讀
//            String line = "";
//            String param = "";
//            while (( line = br.readLine()) != null) {
//                param = br.readLine();
//                System.out.println(param);
//            }
            String param = br.readLine();

            System.out.println(param);
            GetDataServiceImpl getDataService = new GetDataServiceImpl();
            String result = getDataService.getData(param);

//            將呼叫結果寫到socket的輸出流中,以傳送給客戶端
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.println(result);
            printWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
//                關流,現在是在每個執行緒裡
                inputStream.close();
                outputStream.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

處理資料的方法。

package com.wenbing.socket;

public class GetDataServiceImpl {

    public String getData(String param) {
        return "OK-" + param;
    }

}

接下來就是socket客戶端了。客戶端和服務端程式碼基本相同。

package com.wenbing.socket;

import java.io.*;
import java.net.Socket;

public class ServiceClient {

    public static void main(String[] args) throws Exception {
//        向伺服器發出請求建立連線
        Socket socket = new Socket("localhost", 8899);
//        從socket中獲取輸出流
        InputStream inputStream = socket.getInputStream();
        OutputStream outputStream = socket.getOutputStream();

        PrintWriter printWriter = new PrintWriter(outputStream);
        printWriter.println("hello");
        printWriter.flush();

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String result = bufferedReader.readLine();
        System.out.println(result);

        inputStream.close();
        outputStream.close();
        socket.close();
    }

}

簡單的socket小例子,送給java小白們。

紙上得來終覺淺,絕知此事要躬行,一定要跟著敲一敲才更容易理解哦。