大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國(guó)咨詢/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁(yè) 學(xué)習(xí)攻略 Java學(xué)習(xí) 用Java套接字進(jìn)行文件傳輸

用Java套接字進(jìn)行文件傳輸

更新時(shí)間:2022-11-22 09:03:03 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1448次

套接字是一種軟件(邏輯)端點(diǎn),它在服務(wù)器和一個(gè)或多個(gè)客戶端程序之間建立雙向通信。套接字綁定到端口號(hào),以便 TCP 層可以識(shí)別數(shù)據(jù)要發(fā)送到的應(yīng)用程序。應(yīng)用程序軟件定義了一個(gè)套接字,以便它利用底層計(jì)算機(jī)中的端口來(lái)實(shí)現(xiàn)它。這使程序員能夠在其應(yīng)用程序代碼中輕松處理網(wǎng)絡(luò)通信的低級(jí)細(xì)節(jié),例如端口、路由等。

套接字如何工作?

客戶端和服務(wù)器之間的 TCP 套接字通信由幾個(gè)階段組成。

Java實(shí)現(xiàn)TCP套接字通信

在開(kāi)始研究文件傳輸之前,讓我們看看如何在 Java 中實(shí)現(xiàn)套接字通信。在這里,我們將編寫兩個(gè) Java 程序。一個(gè)是在服務(wù)器上運(yùn)行的程序,另一個(gè)是將與服務(wù)器通信的客戶端程序。

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
    private static DataOutputStream dataOutputStream = null;
    private static DataInputStream dataInputStream = null;
    public static void main(String[] args) {
        try(ServerSocket serverSocket = new ServerSocket(5000)){
            System.out.println("listening to port:5000");
            Socket clientSocket = serverSocket.accept();
            System.out.println(clientSocket+" connected\n");
            dataInputStream = new DataInputStream(clientSocket.getInputStream());
            dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
            String message;
            while (true) {
                message = dataInputStream.readUTF();
                System.out.println(message);
                if(message.equalsIgnoreCase("exit()"))
                    break;
            }
            clientSocket.close();
        } catch (Exception e){
            System.out.println(e.toString());
        }
    }
}

在這里,ServerSocket 在本地機(jī)器的 5000 端口打開(kāi)一個(gè)套接字并等待客戶端,server.accept()接受傳入的客戶端連接。

連接客戶端后,將實(shí)例化輸出和輸入流,可用于使用流提供的方法之一與連接的客戶端進(jìn)行read通信write。

在上面的程序中,服務(wù)器循環(huán)并接受來(lái)自客戶端的字符串輸入,dataInputStream.readUTF()然后將其打印在控制臺(tái)上,并在接收到的輸入為exit().

import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
    private static DataOutputStream dataOutputStream = null;
    private static DataInputStream dataInputStream = null;
    private static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        try(Socket socket = new Socket("localhost",5000)){
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            while (true) {
                System.out.print("input> ");
                String message = scanner.nextLine();
                dataOutputStream.writeUTF(message);
                if(message.equalsIgnoreCase("exit()"))
                    break;
            }
        }catch (Exception e){
            System.out.println(e.toString());
        }
    }
}

在這里,Socket 將客戶端應(yīng)用程序連接到在 localhost:5000 偵聽(tīng)的上述服務(wù)器,在連接被接受后輸出和輸入流被實(shí)例化。

該程序接受來(lái)自控制臺(tái)的字符串輸入,然后使用 將其發(fā)送到服務(wù)器,dataOutputStream.writeUTF()并在掃描的輸入匹配時(shí)退出循環(huán)exit()。

運(yùn)行程序:

首先,運(yùn)行Server.java程序,然后運(yùn)行Client.java程序。您將在服務(wù)器端看到連接已接受消息,客戶端將接受輸入??蛻舳随I入的輸入將在服務(wù)器端回顯,以exit()在打破while(true)循環(huán)的客戶端應(yīng)用程序中退出類型。

如果你做到了這一步,你就已經(jīng)獲得了足夠的知識(shí)來(lái)完成任務(wù)。

有什么問(wèn)題?

文件傳輸會(huì)像這樣簡(jiǎn)單:

void sendFile(String filePath){ 
    byte[] buffer = new byte[Integer.MAX_VALUE]; 
    fileInputStream = new FileInputStream(文件路徑); 
    int bytes = fileInputStream.read(buffer,0,buffer.length); 
    dataOutputStream.write(buffer,0,bytes); 
}
void receiveFile(String newFileName){ 
    byte[] buffer = new byte[Integer.MAX_VALUE]; 
    int bytes = dataInputStream.read(buffer,0,buffer.length); 
    fileOutputStream = new FileOutputStream(newFileName); 
    fileOutputStream.write(buffer,0,bytes); 
}

但是這段代碼有兩個(gè)主要問(wèn)題。

文件大?。?/strong>

有人可能會(huì)說(shuō),如果文件大小大于Integer.MAX_VALUE字節(jié),即 2GB,如果是這種情況,這就足夠了。

真正的問(wèn)題是套接字一次只允許 65482 字節(jié),即 64KB,這比上傳到上的大多數(shù)文檔文件大小要小得多網(wǎng)。

多個(gè)文件:

即使文件小于 64KB,此代碼的另一個(gè)問(wèn)題是在發(fā)送多個(gè)文件并檢測(cè) EOF 時(shí),發(fā)送方不會(huì)有任何問(wèn)題,因?yàn)閒ileInputStream.read()它隱式地用于打開(kāi)的文件(因?yàn)?EOF 導(dǎo)致流結(jié)束本身)。

但是在從多個(gè)文件接收數(shù)據(jù)的接收端,dataInputStream一個(gè)接一個(gè)地排隊(duì),并且沒(méi)有任何方法可以分別檢測(cè)每個(gè)文件的 EOF,因此,它將讀取排隊(duì)的整個(gè)字節(jié)作為一個(gè)文件。fileOutputStream.write(buffer)當(dāng)檢測(cè)到第一個(gè)文件的 EOF 并且剩余文件丟失時(shí),使用寫入停止寫入此字節(jié)緩沖區(qū)。

因此,上述代碼僅適用于大小小于 64KB 的單個(gè)文件。

解決方案:

文件大?。哼@個(gè)問(wèn)題的一個(gè)明顯解決方案是將文件分成多個(gè)塊,比如 4KB,然后在循環(huán)語(yǔ)句中通過(guò)套接字發(fā)送它們,并以類似的方式接收,即wile(stream.read(buffer)!=-1){ ... }

多個(gè)文件:這個(gè)問(wèn)題的主要原因是我們不知道接收到的字節(jié)中每個(gè)文件的 EOF dataInputStream,這可以通過(guò)在發(fā)送每個(gè)文件之前發(fā)送文件大小(以字節(jié)為單位)來(lái)解決,因此我們可以從dataInputStream之后中斷讀取文件大小并對(duì)字節(jié)緩沖區(qū)中排隊(duì)的剩余文件重復(fù)相同的操作。

修改代碼:

import java.io.*;
import java.net.Socket;
public class Client {
    private static DataOutputStream dataOutputStream = null;
    private static DataInputStream dataInputStream = null;
    public static void main(String[] args) {
        try(Socket socket = new Socket("localhost",5000)) {
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            sendFile("path/to/file1.pdf");
            sendFile("path/to/file2.pdf");           
            dataInputStream.close();
            dataInputStream.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private static void sendFile(String path) throws Exception{
        int bytes = 0;
        File file = new File(path);
        FileInputStream fileInputStream = new FileInputStream(file);        
        // send file size
        dataOutputStream.writeLong(file.length());  
        // break file into chunks
        byte[] buffer = new byte[4*1024];
        while ((bytes=fileInputStream.read(buffer))!=-1){
            dataOutputStream.write(buffer,0,bytes);
            dataOutputStream.flush();
        }
        fileInputStream.close();
    }
}

文件發(fā)送者

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
    private static DataOutputStream dataOutputStream = null;
    private static DataInputStream dataInputStream = null;
    public static void main(String[] args) {
        try(ServerSocket serverSocket = new ServerSocket(5000)){
            System.out.println("listening to port:5000");
            Socket clientSocket = serverSocket.accept();
            System.out.println(clientSocket+" connected.");
            dataInputStream = new DataInputStream(clientSocket.getInputStream());
            dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
            receiveFile("NewFile1.pdf");
            receiveFile("NewFile2.pdf");
            dataInputStream.close();
            dataOutputStream.close();
            clientSocket.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    private static void receiveFile(String fileName) throws Exception{
        int bytes = 0;
        FileOutputStream fileOutputStream = new FileOutputStream(fileName);        
        long size = dataInputStream.readLong();     // read file size
        byte[] buffer = new byte[4*1024];
        while (size > 0 && (bytes = dataInputStream.read(buffer, 0, (int)Math.min(buffer.length, size))) != -1) {
            fileOutputStream.write(buffer,0,bytes);
            size -= bytes;      // read upto file size
        }
        fileOutputStream.close();
    }
}

文件接收器

提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)

  • 全國(guó)校區(qū) 2025-04-24 搶座中
  • 全國(guó)校區(qū) 2025-05-15 搶座中
  • 全國(guó)校區(qū) 2025-06-05 搶座中
  • 全國(guó)校區(qū) 2025-06-26 搶座中
免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 老司机日日摸夜夜摸精品影院 | 久草在线影视 | 福利视频在线播放 | 不卡网站 | 国产精品成aⅴ人片在线观看 | 久久小视频 | 久久99热这里只有精品国产 | 在线免费观看一级毛片 | 免费看在线爱爱小视频 | 亚洲精品乱码国产精品乱码 | 色综合久久中文综合网 | 国产成人精品男人的天堂538 | 国产精品情侣久久婷婷文字 | 久久精品国产久精国产果冻传媒 | 久久国产精品成人免费 | 精品国产一区二区三区香蕉沈先生 | 一级中文字幕 | 91资源在线 | 国产精品91在线 | 五月婷婷丁香在线视频 | 亚洲 欧美 自拍 卡通 综合 | 午夜国产精品福利在线观看 | 毛茸茸free牲交| 中文字幕三级在线不卡 | 亚洲精品福利一区二区三区 | 中文字幕日韩高清 | 色偷偷青青草原在线视频 | 快射视频欧美 | 久久久久久中文字幕 | 一区二区三区四区产品乱码伦 | 欧美精品一区二区三区视频 | 久久精品亚洲乱码伦伦中文 | 欧美天天性影院 | 亚洲欧美日韩国产色另类 | 久久99精品这里精品动漫6 | 俄罗斯毛片视频 | 国产午夜不卡在线观看视频666 | 奇米影视四色中文字幕 | 99久久国产综合精品成人影院 | 日本在线黄 | 99久久综合精品免费 |