Java Socket編程基礎篇

來源:互聯網
上載者:User

標籤:需要   fixed   block   包括   傳輸資料   兩台   程式設計語言   ide   ble   

原文地址:Java Socket編程----通訊是這樣煉成的

Java最初是作為網路程式設計語言出現的,其對網路提供了高度的支援,使得用戶端和伺服器的溝通變成了現實,而在網路編程中,使用最多的就是Socket。像大家熟悉的QQ、MSN都使用了Socket相關的技術。下面就讓我們一起揭開Socket的神秘面紗。

Socket編程網路基礎知識點:
  1. 兩台電腦間進行通訊需要以下三個條件
    IP地址、協議、連接埠號碼:
    • IP地址:定位應用所在機器的網路位置。(比如家庭住址:北京市朝陽區XX街道XX小區)
    • 連接埠號碼:唯一識別到機器的指定應用。(門牌號)
    • 協議:資料轉送的形式。(TCP、UDP等)
  2. IP地址
    為實現網路中不同電腦之間的通訊,每台電腦都必須有一個唯一的標識---IP地址。

  3. 連接埠
    區分一台主機的多個不同應用程式,連接埠號碼範圍為0-65535,其中0-1023位為系統保留。
    如:HTTP:80 FTP:21 Telnet:23
    IP地址+連接埠號碼組成了所謂的Socket,Socket是網路上啟動並執行程式之間雙向通訊鏈路的終結點,是TCP和UDP的基礎。

  4. Socket通訊端:
    網路上具有唯一標識的IP地址和連接埠組合在一起才能構成唯一能識別的標識符通訊端。

  5. Socket原理機制:
    通訊的兩端都有Socket。
    網路通訊其實就是Socket間的通訊。
    資料在兩個Socket間通過IO傳輸 。

  6. Java中的網路支援
    針對網路通訊的不同層次,Java提供了不同的API,其提供的網路功能有四大類:
    • InetAddress:用於標識網路上的硬體資源,主要是IP地址。
    • URL:統一資源定位器,通過URL可以直接讀取或寫入網路上的資料。
    • Sockets:使用TCP協議實現的網路通訊Socket相關的類
    • Datagram:使用UDP協議,將資料儲存在使用者資料報中,通過網路進行通訊。
InetAddress

InetAddress類代表了一個網路目標地址,包括主機名稱和IP地址資訊。
該類沒有任何構造方法。

// 獲得原生 主機名稱和IP地址InetAddress address = InetAddress.getLocalHost();String hostName = address.getHostName();//擷取電腦名稱(本機主機名稱就是電腦名稱)String hostAddress = address.getHostAddress();//擷取IP地址System.out.println("hostName: " + hostName +" &hostAddress:" + hostAddress);// 擷取遠程機器的 主機名稱和IP地址InetAddress addr = InetAddress.getByName("www.baidu.com"); // 這裡不要加協議 比如:http://www.baidu.comString domainName = addr.getHostName();//獲得主機名稱String ipName = addr.getHostAddress();//獲得IP地址System.out.println("domainName:" + domainName + " &ipName:" + ipName);
使用URL網路資源

通過URL對象的openStream()方法可以得到指定資源的輸入資料流,通過流能夠讀取或訪問網頁上的資源。

//使用URL讀取網頁內容URL url = new URL("http://www.baidu.com");InputStream is = url.openStream();//通過openStream方法擷取資源的位元組輸入資料流InputStreamReader isr = new InputStreamReader(is,"UTF-8");//將位元組輸入資料流轉換為字元輸入資料流,如果不指定編碼,中文可能會出現亂碼BufferedReader br = new BufferedReader(isr);//為字元輸入資料流添加緩衝,提高讀取效率String data = br.readLine();//讀取資料while(data!=null){    System.out.println(data);//輸出資料    data = br.readLine();}br.close();is.close();
TCP編程模型

TCP協議是連線導向的、可靠的、有序的、以位元組流的方式發送資料,通過三向交握方式建立串連,形成傳輸資料的通道,在串連中進行大量資料的傳輸,效率會稍低。

Java中基於TCP協議實現網路通訊的類:

  • 用戶端的Socket類。
  • 伺服器端的ServerSocket類。

Socket通訊的步驟:

  • 建立ServerSocket和Socket。
  • 開啟串連到Socket的輸入和輸出資料流。
  • 按照TCP協議對Socket進行讀寫操作。
  • 關閉輸入輸出資料流,關閉Socket。

伺服器端:

  • 建立ServerSocket對象,綁定監聽連接埠。
  • 通過accept()方法監聽用戶端請求。
  • 串連建立後,通過輸入資料流讀取用戶端發送的請求資訊。
  • 通過輸出資料流向用戶端發送響應資訊。
  • 關閉相關資源。
/** * 基於TCP協議的Socket通訊,實現使用者登入,服務端 *///1、建立一個伺服器端Socket,即ServerSocket,指定綁定的連接埠,並監聽此連接埠ServerSocket serverSocket = new ServerSocket(10086);//1024-65535的某個連接埠//2、調用accept()方法開始監聽,等待用戶端的串連Socket socket = serverSocket.accept();//3、擷取輸入資料流,並讀取用戶端資訊InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);String info = null;while ((info = br.readLine()) != null) {    System.out.println("我是伺服器,用戶端說:" + info);}socket.shutdownInput();//關閉輸入資料流//4、擷取輸出資料流,響應用戶端的請求OutputStream os = socket.getOutputStream();PrintWriter pw = new PrintWriter(os);pw.write("歡迎您!");pw.flush();//5、關閉資源pw.close();os.close();br.close();isr.close();is.close();socket.close();

用戶端:

  • 建立Socket對象,指明需要已連線的服務器的地址和連接埠號碼。
  • 串連建立後,通過輸出資料流向伺服器端發送請求資訊。
  • 通過輸入資料流擷取伺服器響應的資訊
  • 關閉相關資源。
//1、建立用戶端Socket,指定伺服器位址和連接埠Socket socket = new Socket("localhost",10086);//2、擷取輸出資料流,向伺服器端發送資訊OutputStream os = socket.getOutputStream();//位元組輸出資料流PrintWriter pw = new PrintWriter(os);//將輸出資料流封裝成列印流pw.write("使用者名稱:admin;密碼:123");pw.flush();socket.shutdownOutput();//3、擷取輸入資料流,並讀取伺服器端的響應資訊InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));String info = null;while((info=br.readLine())!= null){    System.out.println("我是用戶端,伺服器說:"+info);}//4、關閉資源br.close();is.close();pw.close();os.close();socket.close();
多線程實現伺服器與用戶端之間的通訊。

伺服器端迴圈調用accept()等待用戶端串連。伺服器端接收到資料後即交給一個線程進行非同步處理,然後再次等待用戶端串連。

static ExecutorService executor = Executors.newFixedThreadPool(10);public static void main(String[] args) throws Exception {    /**     * 基於TCP協議的Socket通訊,實現使用者登入,服務端     */    //1、建立一個伺服器端Socket,即ServerSocket,指定綁定的連接埠,並監聽此連接埠    ServerSocket serverSocket = new ServerSocket(10086);//1024-65535的某個連接埠    //2、調用accept()方法開始監聽,等待用戶端的串連    while(true) {        executor.execute(new ServerTask(serverSocket.accept()));    }}static class ServerTask implements Runnable {    Socket socket ;    public ServerTask(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        try {            //3、擷取輸入資料流,並讀取用戶端資訊            InputStream is = socket.getInputStream();            InputStreamReader isr = new InputStreamReader(is);            BufferedReader br = new BufferedReader(isr);            String info = null;            while ((info = br.readLine()) != null) {                System.out.println("我是伺服器,用戶端說:" + info);            }            socket.shutdownInput();//關閉輸入資料流            //4、擷取輸出資料流,響應用戶端的請求            OutputStream os = socket.getOutputStream();            PrintWriter pw = new PrintWriter(os);            pw.write("歡迎您!");            pw.flush();            // demo 就不放在finally裡關閉了            is.close();            isr.close();            os.close();            pw.close();        }catch (Exception e) {            e.printStackTrace();        }    }}
UDP編程模型

UDP協議(使用者資料包通訊協定)是不需連線的、不可靠的、無序的,速度快。

進行資料轉送時,首先將要傳輸的資料定義成資料報(Datagram),大小限制在64k,在資料報中指明資料索要達到的Socket(主機地址和連接埠號碼),然後再將資料報發送出去。

DatagramPacket類:表示資料報包
DatagramSocket類:進行端到端通訊的類

伺服器端實現步驟:

 + 建立DatagramSocket,指定連接埠號碼 + 建立DatagramPacket + 接受用戶端發送的資料資訊 + 讀取資料
//伺服器端,實現基於UDP的使用者登入//1、建立伺服器端DatagramSocket,指定連接埠DatagramSocket socket =new DatagramSocket(10010);//2、建立暫存的資料報文,用於接受用戶端發送的資料byte[] data = new byte[1024];DatagramPacket packet =new DatagramPacket(data,data.length);//3、接受用戶端發送的資料socket.receive(packet);//此方法在接受資料報之前會一致阻塞//4、讀取資料String info = new String(data);System.out.println("我是伺服器,用戶端告訴我:"+info);//向用戶端響應資料//1、定義用戶端的地址、連接埠號碼、資料InetAddress address = packet.getAddress();int port = packet.getPort();byte[] data2 = "歡迎您!".getBytes();//2、建立資料報,包含響應的資料資訊DatagramPacket packet2 = new DatagramPacket(data2,data2.length,address,port);//3、響應用戶端socket.send(packet2);//4、關閉資源socket.close();

用戶端實現步驟:

  • 定義發送訊息。
  • 建立DatagramPacket,包含將要發送的訊息。
  • 建立DatagramSocket。
  • 發送資料。
//用戶端//1、定義伺服器的地址、連接埠號碼、資料InetAddress address = InetAddress.getByName("localhost");int port = 10010;byte[] data = "使用者名稱:admin;密碼:123".getBytes();//2、建立資料報,包含發送的資料資訊DatagramPacket packet = new DatagramPacket(data, data.length, address, port);//3、建立DatagramSocket對象DatagramSocket socket = new DatagramSocket();//4、向伺服器發送資料socket.send(packet);//接受伺服器端響應資料//======================================//1、建立資料報,用於接受伺服器端響應資料byte[] data2 = new byte[1024];DatagramPacket packet2 = new DatagramPacket(data2, data2.length);//2、接受伺服器響應的資料socket.receive(packet2);String raply = new String(data2, 0, packet2.getLength());System.out.println("我是用戶端,伺服器說:" + raply);//4、關閉資源socket.close();
注意問題:

1、多線程的優先順序問題:
根據實際的經驗,適當的降低優先順序,否側可能會有程式運行效率低的情況
2、是否關閉輸出資料流和輸入資料流:
對於同一個socket,如果關閉了輸出資料流,則與該輸出資料流關聯的socket也會被關閉,所以一般不用關閉流,直接關閉socket即可
3、使用TCP通訊傳輸對象,IO中序列化部分
4、socket編程傳遞檔案,IO流部分

Java Socket編程基礎篇

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.