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

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

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

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

網(wǎng)絡(luò)編程是指編寫運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。

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

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

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

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

2.InetAddress類

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

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

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

        // 根據(jù)主機(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對象獲取對應(yīng)的地址
        String hostAddress = host2.getHostAddress();
        System.out.println(hostAddress);

        // 通過InetAddress對象獲取主機(jī)名或者域名
        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提供了兩臺計(jì)算機(jī)之間的通信機(jī)制。 客戶端程序創(chuàng)建一個(gè)套接字,并嘗試連接服務(wù)器的套接字。

當(dāng)連接建立時(shí),服務(wù)器會創(chuàng)建一個(gè) Socket 對象??蛻舳撕头?wù)器現(xiàn)在可以通過對 Socket 對象的寫入和讀取來進(jìn)行通信。

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

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

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

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

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

4.TCP編程

TCP字節(jié)流編程

我們來模擬一個(gè)服務(wù)端和客戶端通信的過程:

服務(wù)端:

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

/**
 * 服務(wù)端
 */
public class SocketServer {
    public static void main(String[] args) throws IOException {
        // 在本地的9999端口進(jìn)行監(jiān)聽
        // 細(xì)節(jié):需要確保9999端口處于空閑狀態(tài)
        ServerSocket serverSocket = new ServerSocket(9999);
        // 沒有客戶端鏈接時(shí),會阻塞,等待鏈接
        // 有客戶端鏈接,則會返回一個(gè)Socket對象
        Socket socket = serverSocket.accept();
        // 通過輸入流獲取客戶端發(fā)來的數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        // 讀取內(nèi)容
        byte[] buf = new byte[1024];
        int readLne = 0;
        while ((readLne = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLne));
        }
        // 關(guān)閉資源
        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 {
        // 鏈接服務(wù)端,由于是測試程序,直接獲取本機(jī)的地址即可
        // 鏈接本機(jī)的9999端口,鏈接成功會返回一個(gè)Socket對象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        // 創(chuàng)建流向服務(wù)器端發(fā)送數(shù)據(jù)
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("Hello Server".getBytes());
        // 關(guān)閉輸出流對象和socket
        outputStream.close();
        socket.close();
        System.out.println("客戶端退出!");
    }
}

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

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

服務(wù)端:

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

/**
 * 服務(wù)端
 */
public class SocketServer {
    public static void main(String[] args) throws IOException {
        // 在本地的9999端口進(jìn)行監(jiān)聽
        // 細(xì)節(jié):需要確保9999端口處于空閑狀態(tài)
        ServerSocket serverSocket = new ServerSocket(9999);
        // 沒有客戶端鏈接時(shí),會阻塞,等待鏈接
        // 有客戶端鏈接,則會返回一個(gè)Socket對象
        Socket socket = serverSocket.accept();
        // 通過輸入流獲取客戶端發(fā)來的數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        // 讀取內(nèi)容
        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());
        // 設(shè)置結(jié)束標(biāo)記
        socket.shutdownOutput();
        // 關(guān)閉資源
        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 {
        // 鏈接服務(wù)端,由于是測試程序,直接獲取本機(jī)的地址即可
        // 鏈接本機(jī)的9999端口,鏈接成功會返回一個(gè)Socket對象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        // 創(chuàng)建流向服務(wù)器端發(fā)送數(shù)據(jù)
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("Hello Server".getBytes());
        // 設(shè)置結(jié)束標(biāo)記
        socket.shutdownOutput();
        // 獲取服務(wù)端的回送數(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));
        }
        // 關(guān)閉輸出流對象和socket
        outputStream.close();
        socket.close();
        System.out.println("客戶端退出!");
    }
}

需要注意:雙端通信需要設(shè)置結(jié)束標(biāo)記,否則會相互等待,陷入僵持

TCP字符流編程

字符流編程,需要使用轉(zhuǎn)換流的技術(shù)

直接上代碼:

客戶端:

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

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

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

服務(wù)端:

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

/**
 * 基于字符流的TCP編程
 * 服務(wù)端
 */

public class CharacterSocketServer {
    public static void main(String[] args) throws IOException {
        // 在本地的9999端口進(jìn)行監(jiān)聽
        // 細(xì)節(jié):需要確保9999端口處于空閑狀態(tài)
        ServerSocket serverSocket = new ServerSocket(9999);
        // 沒有客戶端鏈接時(shí),會阻塞,等待鏈接
        // 有客戶端鏈接,則會返回一個(gè)Socket對象
        Socket socket = serverSocket.accept();
        // 通過輸入流獲取客戶端發(fā)來的數(shù)據(jù)
        InputStream inputStream = socket.getInputStream();
        // IO轉(zhuǎn)換流
        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();
        // 關(guān)閉資源
        br.close();
        bw.close();
        inputStream.close();
        outputStream.close();
        socket.close();
        serverSocket.close();
    }
}

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

服務(wù)端代碼:

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

/**
 * 文件上傳,服務(wù)端
 */
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();
        // 關(guān)閉資源
        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));
        // 此時(shí)的bytes就是文件的字節(jié)內(nèi)容
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        // 通過socket獲取到輸出流,將bytes數(shù)據(jù)發(fā)送給服務(wù)端
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        bos.write(bytes);
        bis.close();
        // 寫入數(shù)據(jù)結(jié)束標(biāo)記
        socket.shutdownOutput();
        // 關(guān)閉資源
        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());
        // 設(shè)置寫入結(jié)束標(biāo)志
        socket.shutdownOutput();
        // 接受服務(wù)器返回的文件字節(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();
    }
}

服務(wù)端代碼:

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文件下載服務(wù)端
 */
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);
        }

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

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(resFileName));
        // 使用工具類將文件保存到一個(gè)字節(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();
    }
}

以上就是一文帶你學(xué)會Java網(wǎng)絡(luò)編程的詳細(xì)內(nèi)容,更多關(guān)于Java網(wǎng)絡(luò)編程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java多線程 線程組原理及實(shí)例詳解

    Java多線程 線程組原理及實(shí)例詳解

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

    基于Java反射的map自動裝配JavaBean工具類設(shè)計(jì)示例代碼

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

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

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

    java dom4j解析xml用到的幾個(gè)方法

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

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

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

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

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

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

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