tcp 的綜合案例

文件上傳案例

文件上傳分析圖解

  1. 【客戶端】輸入流,從硬盤讀取文件數(shù)據(jù)到程序中刊棕。
  2. 【客戶端】輸出流,寫出文件數(shù)據(jù)到服務(wù)端待逞。
  3. 【服務(wù)端】輸入流甥角,讀取文件數(shù)據(jù)到服務(wù)端程序。
  4. 【服務(wù)端】輸出流识樱,寫出文件數(shù)據(jù)到服務(wù)器硬盤中嗤无。
    image.png

    客戶端
/*
    文件上傳案例的客戶端:讀取本地文件,上傳到服務(wù)器,讀取服務(wù)器回寫的數(shù)據(jù)

    明確:
        數(shù)據(jù)源:c:\\1.jpg
        目的地:服務(wù)器

    實(shí)現(xiàn)步驟:
        1.創(chuàng)建一個(gè)本地字節(jié)輸入流FileInputStream對(duì)象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
        2.創(chuàng)建一個(gè)客戶端Socket對(duì)象,構(gòu)造方法中綁定服務(wù)器的IP地址和端口號(hào)
        3.使用Socket中的方法getOutputStream,獲取網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
        4.使用本地字節(jié)輸入流FileInputStream對(duì)象中的方法read,讀取本地文件
        5.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,把讀取到的文件上傳到服務(wù)器
        6.使用Socket中的方法getInputStream,獲取網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
        7.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read讀取服務(wù)回寫的數(shù)據(jù)
        8.釋放資源(FileInputStream,Socket)
 */
public class TCPClient {
    public static void main(String[] args) throws IOException {
        //1.創(chuàng)建一個(gè)本地字節(jié)輸入流FileInputStream對(duì)象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
        FileInputStream fis = new FileInputStream("c:\\1.jpg");
        //2.創(chuàng)建一個(gè)客戶端Socket對(duì)象,構(gòu)造方法中綁定服務(wù)器的IP地址和端口號(hào)
        Socket socket = new Socket("127.0.0.1",8888);
        //3.使用Socket中的方法getOutputStream,獲取網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
        OutputStream os = socket.getOutputStream();
        //4.使用本地字節(jié)輸入流FileInputStream對(duì)象中的方法read,讀取本地文件
        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!=-1){
            //5.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,把讀取到的文件上傳到服務(wù)器
            os.write(bytes,0,len);
        }

        /*
            解決:上傳完文件,給服務(wù)器寫一個(gè)結(jié)束標(biāo)記
            void shutdownOutput() 禁用此套接字的輸出流震束。
            對(duì)于 TCP 套接字,任何以前寫入的數(shù)據(jù)都將被發(fā)送当犯,并且后跟 TCP 的正常連接終止序列垢村。
         */
        socket.shutdownOutput();

        //6.使用Socket中的方法getInputStream,獲取網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
        InputStream is = socket.getInputStream();

        System.out.println("333333333333333333333");

        //7.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read讀取服務(wù)回寫的數(shù)據(jù)
        while((len = is.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }

        System.out.println("444444444444444444  while死循環(huán)打印不到");

        //8.釋放資源(FileInputStream,Socket)
        fis.close();
        socket.close();
    }
}

服務(wù)器端

/*
    文件上傳案例服務(wù)器端:讀取客戶端上傳的文件,保存到服務(wù)器的硬盤,給客戶端回寫"上傳成功"

    明確:
        數(shù)據(jù)源:客戶端上傳的文件
        目的地:服務(wù)器的硬盤 d:\\upload\\1.jpg

    實(shí)現(xiàn)步驟:
        1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
        2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
        3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
        4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
        5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
        6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
        7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
        8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
        9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
        10.釋放資源(FileOutputStream,Socket,ServerSocket)
 */
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
        Socket socket = server.accept();
        //3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
        InputStream is = socket.getInputStream();
        //4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
        File file =  new File("d:\\upload");
        if(!file.exists()){
            file.mkdirs();
        }


        //5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
        FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");
        //6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件

        System.out.println("11111111111111111111");

        int len =0;
        byte[] bytes = new byte[1024];
        while((len = is.read(bytes))!=-1){
            //7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
            fos.write(bytes,0,len);
        }

        System.out.println("22222222222222222222222  while死循環(huán)打印不到");

        //8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
        //9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
        socket.getOutputStream().write("上傳成功".getBytes());
        //10.釋放資源(FileOutputStream,Socket,ServerSocket)
        fos.close();
        socket.close();
        server.close();
    }
}

寫完之后兩個(gè)都沒(méi)有stop,原因分析及解決辦法:


image.png

結(jié)束完以后嚎卫,給服務(wù)器寫一個(gè)結(jié)束標(biāo)記就可以了-------代碼寫入上述代碼中
服務(wù)器端代碼優(yōu)化以后的:

/*
    文件上傳案例服務(wù)器端:讀取客戶端上傳的文件,保存到服務(wù)器的硬盤,給客戶端回寫"上傳成功"

    明確:
        數(shù)據(jù)源:客戶端上傳的文件
        目的地:服務(wù)器的硬盤 d:\\upload\\1.jpg

    實(shí)現(xiàn)步驟:
        1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
        2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
        3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
        4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
        5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
        6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
        7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
        8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
        9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
        10.釋放資源(FileOutputStream,Socket,ServerSocket)
 */
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.創(chuàng)建一個(gè)服務(wù)器ServerSocket對(duì)象,和系統(tǒng)要指定的端口號(hào)
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket對(duì)象中的方法accept,獲取到請(qǐng)求的客戶端Socket對(duì)象
        /*
        讓服務(wù)器一直處于監(jiān)聽(tīng)狀態(tài)(死循環(huán)accept方法)
        有一個(gè)客戶端上傳文件嘉栓,就保存一個(gè)文件
         */
        while(true){
            Socket socket = server.accept();
            /*使用多線程技術(shù),提高程序的效率
            有一個(gè)客戶端上傳文件拓诸,就開(kāi)啟一個(gè)線程侵佃,完成文件的上傳
            */
            new Thread(new Runnable() {
                //完成文件的上傳
                @Override
                public void run() {
                    try {
                        //3.使用Socket對(duì)象中的方法getInputStream,獲取到網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象
                        InputStream is = socket.getInputStream();
                        //4.判斷d:\\upload文件夾是否存在,不存在則創(chuàng)建
                        File file =  new File("d:\\upload");
                        if(!file.exists()){
                            file.mkdirs();
                        }
                        /*自定義一個(gè)文件的命名規(guī)則。防止同名的文件被覆蓋
                        規(guī)則:域名+毫秒值+隨機(jī)數(shù)
                        */
                        String fileName = "itcast"+System.currentTimeMillis()+new Random().nextInt(99999)+".jpg"
                        //5.創(chuàng)建一個(gè)本地字節(jié)輸出流FileOutputStream對(duì)象,構(gòu)造方法中綁定要輸出的目的地
                        FileOutputStream fos = new FileOutputStream(file+"\\"+fileName);
                        //6.使用網(wǎng)絡(luò)字節(jié)輸入流InputStream對(duì)象中的方法read,讀取客戶端上傳的文件
                        int len =0;
                        byte[] bytes = new byte[1024];
                        while((len = is.read(bytes))!=-1){
                            //7.使用本地字節(jié)輸出流FileOutputStream對(duì)象中的方法write,把讀取到的文件保存到服務(wù)器的硬盤上
                            fos.write(bytes,0,len);
                        }
                        //8.使用Socket對(duì)象中的方法getOutputStream,獲取到網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象
                        //9.使用網(wǎng)絡(luò)字節(jié)輸出流OutputStream對(duì)象中的方法write,給客戶端回寫"上傳成功"
                        socket.getOutputStream().write("上傳成功".getBytes());
                        //10.釋放資源(FileOutputStream,Socket,ServerSocket)
                        fos.close();
                        socket.close();
                    }catch (IOException e){
                        System.out.println(e);
                    }
                }
            }).start();
        //server.close();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奠支,一起剝皮案震驚了整個(gè)濱河市馋辈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倍谜,老刑警劉巖迈螟,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異尔崔,居然都是意外死亡答毫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門您旁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烙常,“玉大人,你說(shuō)我怎么就攤上這事鹤盒。” “怎么了侦副?”我有些...
    開(kāi)封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵侦锯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我秦驯,道長(zhǎng)尺碰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任译隘,我火速辦了婚禮亲桥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘固耘。我一直安慰自己题篷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布厅目。 她就那樣靜靜地躺著番枚,像睡著了一般法严。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上葫笼,一...
    開(kāi)封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天深啤,我揣著相機(jī)與錄音,去河邊找鬼路星。 笑死溯街,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洋丐。 我是一名探鬼主播呈昔,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼垫挨!你這毒婦竟也來(lái)了韩肝?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤九榔,失蹤者是張志新(化名)和其女友劉穎哀峻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哲泊,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剩蟀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了切威。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片育特。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖先朦,靈堂內(nèi)的尸體忽然破棺而出缰冤,到底是詐尸還是另有隱情,我是刑警寧澤喳魏,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布棉浸,位于F島的核電站,受9級(jí)特大地震影響刺彩,放射性物質(zhì)發(fā)生泄漏迷郑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一创倔、第九天 我趴在偏房一處隱蔽的房頂上張望嗡害。 院中可真熱鬧,春花似錦畦攘、人聲如沸霸妹。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抑堡。三九已至摆出,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間首妖,已是汗流浹背偎漫。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留有缆,地道東北人象踊。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像棚壁,于是被迫代替她去往敵國(guó)和親杯矩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容