欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你學會Java網(wǎng)絡編程

 更新時間:2022年08月08日 08:31:39   作者:世界盡頭與你  
網(wǎng)絡編程是指編寫運行在多個設備(計算機)的程序,這些設備都通過網(wǎng)絡連接起來。這篇文章將帶大家深入了解一下Java的網(wǎng)絡編程,需要的可以了解一下

1.java網(wǎng)絡編程概述

網(wǎng)絡編程是指編寫運行在多個設備(計算機)的程序,這些設備都通過網(wǎng)絡連接起來。

java.net 包中 J2SE 的 API 包含有類和接口,它們提供低層次的通信細節(jié)。你可以直接使用這些類和接口,來專注于解決問題,而不用關注通信細節(jié)。

java.net 包中提供了兩種常見的網(wǎng)絡協(xié)議的支持:

TCP:TCP(英語:Transmission Control Protocol,傳輸控制協(xié)議)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,TCP 層是位于 IP 層之上,應用層之下的中間層。TCP保障了兩個應用程序之間的可靠通信。通常用于互聯(lián)網(wǎng)協(xié)議,被稱 TCP / IP。

UDP:UDP (英語:User Datagram Protocol,用戶數(shù)據(jù)報協(xié)議),位于 OSI模型的傳輸層。一個無連接的協(xié)議。提供了應用程序之間要發(fā)送數(shù)據(jù)的數(shù)據(jù)報。由于UDP缺乏可靠性且屬于無連接協(xié)議,所以應用程序通常必須容許一些丟失、錯誤或重復的數(shù)據(jù)包。

2.InetAddress類

這個類表示互聯(lián)網(wǎng)協(xié)議(IP)地址。下面演示了 Socket 編程時比較有用的方法:

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * InetAddress類演示
 */
public class InetAddressTest {
    public static void main(String[] args) throws UnknownHostException {
        // 獲取本機的InetAddress對象:主機名 + IP地址
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);

        // 根據(jù)主機名獲取InetAddress對象
        InetAddress host1 = InetAddress.getByName("Dahe-Windows11");
        System.out.println(host1);

        // 根據(jù)域名獲取InetAddress對象
        InetAddress host2 = InetAddress.getByName("www.baidu.com");
        System.out.println(host2);

        // 通過InetAddress對象獲取對應的地址
        String hostAddress = host2.getHostAddress();
        System.out.println(hostAddress);

        // 通過InetAddress對象獲取主機名或者域名
        String hostName = host2.getHostName();
        System.out.println(hostName);
    }
}

輸出:

XXX-WindowsXX/192.168.0.1
XXX-WindowsXX/192.168.0.1
www.baidu.com/39.156.66.18
39.156.66.18
www.baidu.com

3.Socket 編程

套接字使用TCP提供了兩臺計算機之間的通信機制。 客戶端程序創(chuàng)建一個套接字,并嘗試連接服務器的套接字。

當連接建立時,服務器會創(chuàng)建一個 Socket 對象??蛻舳撕头掌鳜F(xiàn)在可以通過對 Socket 對象的寫入和讀取來進行通信。

java.net.Socket 類代表一個套接字,并且 java.net.ServerSocket 類為服務器程序提供了一種來監(jiān)聽客戶端,并與他們建立連接的機制。

以下步驟在兩臺計算機之間使用套接字建立TCP連接時會出現(xiàn):

  • 服務器實例化一個 ServerSocket 對象,表示通過服務器上的端口通信。
  • 服務器調用 ServerSocket 類的 accept() 方法,該方法將一直等待,直到客戶端連接到服務器上給定的端口。
  • 服務器正在等待時,一個客戶端實例化一個 Socket 對象,指定服務器名稱和端口號來請求連接。
  • Socket 類的構造函數(shù)試圖將客戶端連接到指定的服務器和端口號。如果通信被建立,則在客戶端創(chuàng)建一個 Socket對象能夠與服務器進行通信。
  • 在服務器端,accept() 方法返回服務器上一個新的 socket 引用,該 socket 連接到客戶端的 socket。

連接建立后,通過使用 I/O 流在進行通信,每一個socket都有一個輸出流和一個輸入流,客戶端的輸出流連接到服務器端的輸入流,而客戶端的輸入流連接到服務器端的輸出流。

TCP 是一個雙向的通信協(xié)議,因此數(shù)據(jù)可以通過兩個數(shù)據(jù)流在同一時間發(fā)送

4.TCP編程

TCP字節(jié)流編程

我們來模擬一個服務端和客戶端通信的過程:

服務端:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服務端
 */
public class SocketServer {
    public static void main(String[] args) throws IOException {
        // 在本地的9999端口進行監(jiān)聽
        // 細節(jié):需要確保9999端口處于空閑狀態(tài)
        ServerSocket serverSocket = new ServerSocket(9999);
        // 沒有客戶端鏈接時,會阻塞,等待鏈接
        // 有客戶端鏈接,則會返回一個Socket對象
        Socket socket = serverSocket.accept();
        // 通過輸入流獲取客戶端發(fā)來的數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        // 讀取內容
        byte[] buf = new byte[1024];
        int readLne = 0;
        while ((readLne = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLne));
        }
        // 關閉資源
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

客戶端:

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 客戶端
 */
public class SocketClient {
    public static void main(String[] args) throws IOException {
        // 鏈接服務端,由于是測試程序,直接獲取本機的地址即可
        // 鏈接本機的9999端口,鏈接成功會返回一個Socket對象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        // 創(chuàng)建流向服務器端發(fā)送數(shù)據(jù)
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("Hello Server".getBytes());
        // 關閉輸出流對象和socket
        outputStream.close();
        socket.close();
        System.out.println("客戶端退出!");
    }
}

同時運行服務端和客戶端,該示例代碼,客戶端會向服務端發(fā)送一個流信息:Hello Server

接下來,我們來看一個更為復雜的例子:實現(xiàn)客戶端和服務端的雙通信

服務端:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服務端
 */
public class SocketServer {
    public static void main(String[] args) throws IOException {
        // 在本地的9999端口進行監(jiān)聽
        // 細節(jié):需要確保9999端口處于空閑狀態(tài)
        ServerSocket serverSocket = new ServerSocket(9999);
        // 沒有客戶端鏈接時,會阻塞,等待鏈接
        // 有客戶端鏈接,則會返回一個Socket對象
        Socket socket = serverSocket.accept();
        // 通過輸入流獲取客戶端發(fā)來的數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        // 讀取內容
        byte[] buf = new byte[1024];
        int readLne = 0;
        while ((readLne = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLne));
        }
        // 向客戶端回送消息
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,client".getBytes());
        // 設置結束標記
        socket.shutdownOutput();
        // 關閉資源
        inputStream.close();
        outputStream.close();
        socket.close();
        serverSocket.close();
    }
}

客戶端:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 客戶端
 */
public class SocketClient {
    public static void main(String[] args) throws IOException {
        // 鏈接服務端,由于是測試程序,直接獲取本機的地址即可
        // 鏈接本機的9999端口,鏈接成功會返回一個Socket對象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        // 創(chuàng)建流向服務器端發(fā)送數(shù)據(jù)
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("Hello Server".getBytes());
        // 設置結束標記
        socket.shutdownOutput();
        // 獲取服務端的回送數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLen));
        }
        // 關閉輸出流對象和socket
        outputStream.close();
        socket.close();
        System.out.println("客戶端退出!");
    }
}

需要注意:雙端通信需要設置結束標記,否則會相互等待,陷入僵持

TCP字符流編程

字符流編程,需要使用轉換流的技術

直接上代碼:

客戶端:

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

/**
 * 基于字符流的TCP編程
 * 客戶端
 */

public class CharacterSocketClient {
    public static void main(String[] args) throws IOException {
        // 鏈接服務端,由于是測試程序,直接獲取本機的地址即可
        // 鏈接本機的9999端口,鏈接成功會返回一個Socket對象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        // 創(chuàng)建流向服務器端發(fā)送數(shù)據(jù)
        OutputStream outputStream = socket.getOutputStream();
        // 使用IO轉換流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
        bw.write("hello,server 字符流");
        // 插入換行符,表示寫入的內容結束
        bw.newLine();
        // 使用字符流,必須手動刷新,否則數(shù)據(jù)將不會寫入通道
        bw.flush();
        // 設置結束標記
        socket.shutdownOutput();
        // 獲取服務端的回送數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        String s = br.readLine();
        System.out.println(s);
        // 關閉輸出流對象和socket
        br.close();
        bw.close();
        outputStream.close();
        socket.close();
        System.out.println("客戶端退出!");
    }
}

服務端:

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

/**
 * 基于字符流的TCP編程
 * 服務端
 */

public class CharacterSocketServer {
    public static void main(String[] args) throws IOException {
        // 在本地的9999端口進行監(jiān)聽
        // 細節(jié):需要確保9999端口處于空閑狀態(tài)
        ServerSocket serverSocket = new ServerSocket(9999);
        // 沒有客戶端鏈接時,會阻塞,等待鏈接
        // 有客戶端鏈接,則會返回一個Socket對象
        Socket socket = serverSocket.accept();
        // 通過輸入流獲取客戶端發(fā)來的數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        // IO轉換流
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        // 必須使用readLine方式來讀
        String s = br.readLine();
        System.out.println(s);
        // 向客戶端回送消息
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
        bw.write("Hello,Client 字符流");
        bw.newLine();
        bw.flush();
        // 關閉資源
        br.close();
        bw.close();
        inputStream.close();
        outputStream.close();
        socket.close();
        serverSocket.close();
    }
}

5.網(wǎng)絡上傳文件

服務端代碼:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 文件上傳,服務端
 */
public class TCPFileUploadServer {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(8888);
        Socket socket = serverSocket.accept();
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        String destFilePath = "networkprogramming\\tcp\\color.jpg";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
        bos.write(bytes);
        bos.close();
        // 關閉資源
        bis.close();
        socket.close();
        serverSocket.close();
    }
}

客戶端代碼:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 文件上傳,客戶端
 */
public class TCPFileUploadClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
        // 創(chuàng)建讀取磁盤文件的輸入流
        String filePath = "D:\\color.jpg";
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
        // 此時的bytes就是文件的字節(jié)內容
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        // 通過socket獲取到輸出流,將bytes數(shù)據(jù)發(fā)送給服務端
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        bos.write(bytes);
        bis.close();
        // 寫入數(shù)據(jù)結束標記
        socket.shutdownOutput();
        // 關閉資源
        bos.close();
        socket.close();
    }
}

6.TCP文件下載

客戶端代碼:

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

/**
 * TCP文件下載客戶端
 */
public class TCPFileDownloadClient {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入下載文件名:");
        String downloadFileName = scanner.next();
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(downloadFileName.getBytes());
        // 設置寫入結束標志
        socket.shutdownOutput();
        // 接受服務器返回的文件字節(jié)數(shù)組
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        // 將文件寫入磁盤
        String filePath = "D:\\" + downloadFileName + ".jpg";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        bos.write(bytes);
        bos.close();
        socket.close();
        outputStream.close();
        bis.close();
    }
}

服務端代碼:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * TCP文件下載服務端
 */
public class TCPFileDownloadServer {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(9999);
        Socket socket = serverSocket.accept();
        // 讀取客戶端發(fā)送的要下載的文件名稱
        InputStream inputStream = socket.getInputStream();
        byte[] b = new byte[1024];
        int len = 0;
        // 客戶端要下載的文件名
        String downloadFileName = "";
        while ((len = inputStream.read(b)) != -1) {
            downloadFileName += new String(b, 0, len);
        }

        // 提供給客戶端下載的實際文件名
        String resFileName = "";
        if ("color".equals(downloadFileName)) {
            resFileName = "networkprogramming\\tcp\\color.jpg";
        } else {
            resFileName = "networkprogramming\\tcp\\fish.jpg";
        }

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(resFileName));
        // 使用工具類將文件保存到一個字節(jié)數(shù)組中
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        // 寫入到數(shù)據(jù)通道,返回給客戶端
        bos.write(bytes);
        socket.shutdownOutput();
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

以上就是一文帶你學會Java網(wǎng)絡編程的詳細內容,更多關于Java網(wǎng)絡編程的資料請關注腳本之家其它相關文章!

相關文章

  • spring boot 默認異常處理的實現(xiàn)

    spring boot 默認異常處理的實現(xiàn)

    這篇文章主要介紹了spring boot 默認異常處理的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Vert-x-通過異步的方式使用JDBC連接SQL

    Vert-x-通過異步的方式使用JDBC連接SQL

    在這篇文章中,我們將會看到怎樣在vert.x應用中使用HSQL,當然也可以使用任意JDBC,以及使用vertx-jdbc-client提供的異步的API,這篇文章的代碼在github
    2016-01-01
  • Java面向對象之猜拳游戲

    Java面向對象之猜拳游戲

    這篇文章主要為大家詳細介紹了Java面向對象之猜拳游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Java多線程 線程組原理及實例詳解

    Java多線程 線程組原理及實例詳解

    這篇文章主要介紹了Java多線程 線程組原理及實例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • 基于Java反射的map自動裝配JavaBean工具類設計示例代碼

    基于Java反射的map自動裝配JavaBean工具類設計示例代碼

    這篇文章主要給大家介紹了關于基于Java反射的map自動裝配JavaBean工具類設計的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用java具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2018-10-10
  • Java數(shù)字圖像處理之圖像灰度處理

    Java數(shù)字圖像處理之圖像灰度處理

    這篇文章主要為大家詳細介紹了Java數(shù)字圖像處理之圖像灰度處理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • java dom4j解析xml用到的幾個方法

    java dom4j解析xml用到的幾個方法

    這篇文章主要介紹了java dom4j解析xml用到的幾個方法,有需要的朋友可以參考一下
    2013-12-12
  • controller函數(shù)中參數(shù)列表使用多個@RequestBody問題

    controller函數(shù)中參數(shù)列表使用多個@RequestBody問題

    這篇文章主要介紹了controller函數(shù)中參數(shù)列表使用多個@RequestBody問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • java實現(xiàn)二分法查找出數(shù)組重復數(shù)字

    java實現(xiàn)二分法查找出數(shù)組重復數(shù)字

    這篇文章主要為大家詳細介紹了java實現(xiàn)二分法查找出數(shù)組重復數(shù)字,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • SpringBoot?屬性配置中獲取值的方式

    SpringBoot?屬性配置中獲取值的方式

    這篇文章主要介紹了SpringBoot?屬性配置中獲取值的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評論