最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你學(xué)會(huì)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)用程序通常必須容許一些丟失、錯(cuò)誤或重復(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提供了兩臺(tái)計(jì)算機(jī)之間的通信機(jī)制。 客戶端程序創(chuàng)建一個(gè)套接字,并嘗試連接服務(wù)器的套接字。

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

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

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

  • 服務(wù)器實(shí)例化一個(gè) ServerSocket 對象,表示通過服務(wù)器上的端口通信。
  • 服務(wù)器調(diào)用 ServerSocket 類的 accept() 方法,該方法將一直等待,直到客戶端連接到服務(wù)器上給定的端口。
  • 服務(wù)器正在等待時(shí),一個(gè)客戶端實(shí)例化一個(gè) Socket 對象,指定服務(wù)器名稱和端口號(hào)來請求連接。
  • Socket 類的構(gòu)造函數(shù)試圖將客戶端連接到指定的服務(wù)器和端口號(hào)。如果通信被建立,則在客戶端創(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í),會(huì)阻塞,等待鏈接
        // 有客戶端鏈接,則會(huì)返回一個(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端口,鏈接成功會(huì)返回一個(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ù)端和客戶端,該示例代碼,客戶端會(huì)向服務(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í),會(huì)阻塞,等待鏈接
        // 有客戶端鏈接,則會(huì)返回一個(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端口,鏈接成功會(huì)返回一個(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)記,否則會(huì)相互等待,陷入僵持

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端口,鏈接成功會(huì)返回一個(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();
        // 使用字符流,必須手動(dòng)刷新,否則數(shù)據(jù)將不會(huì)寫入通道
        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í),會(huì)阻塞,等待鏈接
        // 有客戶端鏈接,則會(huì)返回一個(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é)會(huì)Java網(wǎng)絡(luò)編程的詳細(xì)內(nèi)容,更多關(guān)于Java網(wǎng)絡(luò)編程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java貪心算法超詳細(xì)講解

    Java貪心算法超詳細(xì)講解

    人之初性本善,但是隨著自身的經(jīng)歷、生活環(huán)境等因素的影響,人逐漸會(huì)生出貪嗔癡。實(shí)際上不光人有貪念,我們的算法也會(huì)有貪念,今天就和大家介紹下一個(gè)有貪念的算法模型---貪心算法,看看一個(gè)算法是怎么產(chǎn)生貪念的
    2022-05-05
  • Java外觀模式解讀,讓你的代碼優(yōu)雅又高效

    Java外觀模式解讀,讓你的代碼優(yōu)雅又高效

    外觀模式(Facade?Pattern)是一種常用的結(jié)構(gòu)型設(shè)計(jì)模式,它為復(fù)雜的子系統(tǒng)提供一個(gè)簡單的接口,隱藏復(fù)雜的實(shí)現(xiàn)細(xì)節(jié),本文就來講講它是如何簡化代碼,提高可維護(hù)性的
    2023-05-05
  • springboot 跨域配置類及跨域請求配置

    springboot 跨域配置類及跨域請求配置

    這篇文章主要介紹了springboot 跨域配置類及跨域請求配置,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • Java使用RandomAccessFile類對文件進(jìn)行讀寫

    Java使用RandomAccessFile類對文件進(jìn)行讀寫

    本篇文章主要介紹了Java使用RandomAccessFile類對文件進(jìn)行讀寫,詳細(xì)的介紹了RandomAccessFile類的使用技巧和實(shí)例應(yīng)用,有興趣的可以了解一下
    2017-04-04
  • java String類功能、原理與應(yīng)用案例【統(tǒng)計(jì)、判斷、轉(zhuǎn)換等】

    java String類功能、原理與應(yīng)用案例【統(tǒng)計(jì)、判斷、轉(zhuǎn)換等】

    這篇文章主要介紹了java String類功能、原理與應(yīng)用案例,結(jié)合實(shí)例形式詳細(xì)分析了java String類的基本功能、構(gòu)造方法,以及使用String類實(shí)現(xiàn)統(tǒng)計(jì)、判斷、轉(zhuǎn)換等功能相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • Java實(shí)現(xiàn)數(shù)字金額轉(zhuǎn)化為英文金額功能

    Java實(shí)現(xiàn)數(shù)字金額轉(zhuǎn)化為英文金額功能

    在處理財(cái)務(wù)數(shù)據(jù)時(shí),有時(shí)需要將數(shù)字形式的金額轉(zhuǎn)換成英文描述的形式,比如在生成正式文件或發(fā)票時(shí),本文將介紹如何使用Java實(shí)現(xiàn)這一功能,需要的朋友可以參考下
    2025-03-03
  • java跳出for循環(huán)的三種常見方法

    java跳出for循環(huán)的三種常見方法

    這篇文章主要給大家介紹了關(guān)于java跳出for循環(huán)的三種常見方法,需要的朋友可以參考下
    2023-07-07
  • java實(shí)現(xiàn)把對象數(shù)組通過excel方式導(dǎo)出的功能

    java實(shí)現(xiàn)把對象數(shù)組通過excel方式導(dǎo)出的功能

    本文主要介紹了java實(shí)現(xiàn)把對象數(shù)組通過excel方式導(dǎo)出的功能的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-03-03
  • Java并發(fā)編程之ConcurrentLinkedQueue源碼詳解

    Java并發(fā)編程之ConcurrentLinkedQueue源碼詳解

    今天帶小伙伴們學(xué)習(xí)一下Java并發(fā)編程之Java ConcurrentLinkedQueue源碼,本篇文章詳細(xì)分析了ConcurrentLinkedQueue源碼,有代碼示例,對正在學(xué)習(xí)java的小伙伴們很有幫助喲,需要的朋友可以參考下
    2021-05-05
  • 詳解Java中的阻塞隊(duì)列

    詳解Java中的阻塞隊(duì)列

    在去年的面試過程中,被面試官問道“阻塞隊(duì)列”這個(gè)問題,因?yàn)楫?dāng)時(shí)并沒有對此問題進(jìn)行深入理解,只是按照自己的理解說明了該問題,最后面試結(jié)果也不太好,今天對該問題進(jìn)行簡要的面試并記錄如下;如有錯(cuò)誤,歡迎指正,需要的朋友可以參考下
    2021-06-06

最新評論

嘉祥县| 大庆市| 依兰县| 富阳市| 潼关县| 醴陵市| 江阴市| 兖州市| 旬邑县| 宁安市| 汝阳县| 南郑县| 镇巴县| 拜城县| 林口县| 界首市| 德州市| 黄平县| 普洱| 苏尼特右旗| 鹤峰县| 山阳县| 通化市| 海城市| 临猗县| 柳林县| 阿合奇县| 颍上县| 密山市| 故城县| 牡丹江市| 赤城县| 会宁县| 阿拉尔市| 孝义市| 仲巴县| 阿瓦提县| 曲松县| 思南县| 青州市| 闵行区|