馮鋼
摘要:針對Java的Socket網(wǎng)絡(luò)編程,文中通過分析對象的序列、對象流的知識,探討對象流在Socket編程中的應(yīng)用方法,結(jié)合實例分析字符流和對象流在實現(xiàn)復(fù)雜數(shù)據(jù)在網(wǎng)絡(luò)傳輸方法,對于復(fù)雜數(shù)據(jù)的網(wǎng)絡(luò)傳輸利用對象流可提高編程效率。
關(guān)鍵詞:Socket ;對象;序列化
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2014)23-5445-04
在面向Internet的網(wǎng)絡(luò)信息系統(tǒng)中,客戶/服務(wù)得到廣泛應(yīng)用,在Java的網(wǎng)絡(luò)編程中,網(wǎng)絡(luò)通信程序主要是基于Java的Socket來實現(xiàn)。常用的輸入/輸出流主要是字節(jié)流和字符流,通過字節(jié)流和字符流可方便在客戶程序和服務(wù)器程序間傳送數(shù)據(jù),一般簡單數(shù)據(jù)而言利用字節(jié)流或字符流可方便解決,對于復(fù)雜數(shù)據(jù)而言,利用上述方法也能完成,但在傳輸前要對傳輸?shù)臄?shù)據(jù)按定義的規(guī)則進行包裝,在接收到時數(shù)據(jù)時又要對獲取的數(shù)據(jù)近規(guī)則進行解析,實現(xiàn)較為繁瑣,如果利用對象的序列化及對象流可方便解決復(fù)雜數(shù)據(jù)的傳輸問題,可簡化數(shù)據(jù)的包裝與解析的過程,提高編程效率。
1 對象序列化及對象流
1.1 對象的序列化
當兩個進程在進行遠程通信時,彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會以二進制序列的形式在網(wǎng)絡(luò)上傳送。如果傳輸是Java對象,則發(fā)送方需要把這個Java對象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為Java對象。
把Java對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化。
把字節(jié)序列恢復(fù)為Java對象的過程稱為對象的反序列化。
對象的序列化主要有兩種用途:
1) 把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個文件中;
2) 在網(wǎng)絡(luò)上傳送對象的字節(jié)序列。
1.2 對象流
java.io.ObjectOutputStream代表對象輸出流,它的writeObject(Object obj)方法可對參數(shù)指定的obj對象進行序列化,把得到的字節(jié)序列寫到一個目標輸出流中。
java.io.ObjectInputStream代表對象輸入流,它的readObject()方法從一個源輸入流中讀取字節(jié)序列,再把它們反序列化為一個對象,并將其返回。、
只有實現(xiàn)了Serializable和Externalizable接口的類的對象才能被序列化。Externalizable接口繼承自Serializable接口,實現(xiàn)Externalizable接口的類完全由自身來控制序列化的行為,而僅實現(xiàn)Serializable接口的類可以采用默認的序列化方式 。
對象序列化包括如下步驟:
1) 創(chuàng)建一個對象輸出流,它可以包裝一個其他類型的目標輸出流,如文件輸出流;
2) 通過對象輸出流的writeObject()方法寫對象。
對象反序列化的步驟如下:
1) 創(chuàng)建一個對象輸入流,它可以包裝一個其他類型的源輸入流,如文件輸入流;
2) 通過對象輸入流的readObject()方法讀取對象。
2 實例分析
編寫網(wǎng)絡(luò)注冊程序,客戶程序?qū)崿F(xiàn)用戶注冊,注冊信息:用戶名,密碼、聯(lián)系電話、所學專業(yè),服務(wù)程序?qū)崿F(xiàn)用戶注冊信息的獲取,后繼略。
2.1 利用字符流實現(xiàn)
1) 客戶端注冊程序
在注冊客戶程序中,首先連接服務(wù)器,點擊注冊按鈕,獲取用戶的注冊信息,將用戶構(gòu)建為字符串,用“,”作為分隔符,便于服務(wù)端程序解析。范例實現(xiàn)如下:
服務(wù)端接收程序在接收到客戶發(fā)出的信息后,由于得到是一字符串,必須從中解析出用戶的存著信息(用戶名、密碼、聯(lián)系電話、專業(yè))等信息,然后才能進行后繼相關(guān)操作,解析的方法有多種,范例如下:通過字符型數(shù)據(jù)的split(",")方法,分隔相關(guān)信息存入數(shù)組mess,后繼通過讀取數(shù)組mess中的數(shù)據(jù)完成相關(guān)操作,如:顯示、存入數(shù)據(jù)庫等
2.2 利用對象流實現(xiàn)
1) 創(chuàng)建用戶信息類,實現(xiàn)Serializable接口,用于對象的序列化。
2) 客戶端注冊程序
在注冊客戶程序中,首先連接服務(wù)器,點擊注冊按鈕,獲取用戶的注冊信息,通過獲取信息構(gòu)建對象,利用對象流進行網(wǎng)絡(luò)傳輸,范例實現(xiàn)如下:
① 連接服務(wù)器,初始化對象流
3) 服務(wù)端接收程序
服務(wù)端接收程序通過對象流獲取對象序列的數(shù)據(jù)可直接轉(zhuǎn)換為相關(guān)對象。
① 啟動服務(wù)器,等待客戶連接,連接成功后,創(chuàng)建對象輸入流,用戶于數(shù)據(jù)讀取
ServerSocket ss=new ServerSocket(7777);
Socket sc = ss.accept();
this.jLabMess.setText("客戶連接成功");
BufferedInputStream in = new BufferedInputStream(sc.getInputStream());
//初始化輸入對象流
bread = new ObjectInputStream(in);
//啟動線程,接收客戶注冊數(shù)據(jù)
new MyThread().start();
② 用戶有數(shù)據(jù)發(fā)出,通過對象輸入流readObject()方法,直接的獲取相關(guān)數(shù)據(jù)
UserInfo utem=(UserInfo)bread.readObject();
//后繼操作,如顯示等……
jTextArea1.append("用戶名:"+utem.getName()+"\n");
jTextArea1.append("密碼:"+utem.getPassword()+"\n");
jTextArea1.append("電話:"+utem.getPhone()+"\n");
jTextArea1.append("專業(yè):"+utem.getProfession());
運行效果:
3 結(jié)束語
Java的網(wǎng)絡(luò)編程主要通過Socket完成,文中先介紹了對象的序列化及對象流的相關(guān)知識,在設(shè)計范例分別通過字符流和對象流完成相關(guān)設(shè)計,通過二者比較,在復(fù)雜數(shù)據(jù)傳輸中,利用對象可方便解決利用字符流傳輸中的數(shù)據(jù)傳送前的包裝和數(shù)據(jù)接收后的解析問題,充分利用對象流可為編程帶來了方便,提高編程效率。
參考文獻:
[1] Bruce Eckel.Java. Java編程思想[M].陳昊鵬,譯.北京:機械工業(yè)出版社,2009.
[2] 徐義晗,史夢安,史志英.Java程序設(shè)計項目化教程[M].北京:北京大學出版社,2011.
[3] 許文勇.基于Socket的網(wǎng)絡(luò)編程技術(shù)及其實現(xiàn)[J].無線互聯(lián)科技,2014(5):17
[4] 賈振華.Java語言程序設(shè)計[M].北京:中國水利水電出版社,2001.