導航:首頁 > 編程語言 > java網路編程精解源代碼

java網路編程精解源代碼

發布時間:2023-06-08 18:06:32

java經典教材

隨著JAVA行業日益的發展,高薪資也吸引到各行各業的從業者。下面就推薦幾本JAVA經典教材供大家參考:
1. 《Java經典實例》收集了Java開發人員經常遇到的成百個問題的解決方案,涵蓋了Java應用的方方面面,堪稱講述Java應用的網路全書。
2. 《Java 實時編程》主要講述使用Java RTS進行Java實時編程的各類主題。主要內容包括3個部分:第一部分"實時計算概念",明確定義計算領域中的實時概念,並討論了許多實時應用程序設計和開發的理論;第二部分"高級Java RTS",提供充足的示例代碼來說明Java RTS的內部運作機制及其使用;第三部分"使用Java RTS",討論了實際的案例研究。
3. 《Java網路編程精解》,通過這本書讀者不僅可以掌握網路編程的實用技術,還可以進一步提高按照面向對象的思想來設計和編寫Java軟體的能力。

② java socket網路編程

//==============Server.java=================//
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(12345);
System.out.println("伺服器就緒,請啟動客戶端.");
Socket so = s.accept();
byte[] buff = new byte[1024];
int read = so.getInputStream().read(buff);
String[] abc=new String(buff,0,read).split("\\D+");
int a = Integer.parseInt(abc[0]);
int b = Integer.parseInt(abc[1]);
int c = Integer.parseInt(abc[2]);
if(!cbt(a,b,c))
so.getOutputStream().write("輸入的數據無法組成三角形.".getBytes());
else
so.getOutputStream().write(getArea(a,b,c).getBytes());
so.getOutputStream().flush();
so.close();
s.close();
}

private static String getArea(int a, int b, int c) {
float s = (a+b+c)/2f;
return "面積: "+Math.sqrt(s*(s-a)*(s-b)*(s-c));
}

private static boolean cbt(int a, int b, int c) {
return a>0&&b>0&&c>0&&a+b>c&&b+c>a&&a+c>b;
}
}

//=================Client.java======================//
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("輸入三角形的三邊並用逗號隔開,如: (3,4,5) ");
byte[] buff=new byte[64];
int r = System.in.read(buff);
String ipaddr = "localhost";//根據情況改變,在本機調試就不改了
Socket so = new Socket(ipaddr,12345);
so.getOutputStream().write(new String(buff,0,r).getBytes());
r = so.getInputStream().read(buff);
so.close();
String rs = new String(buff,0,r);
System.out.println(rs);
}

}

//先啟動Server,再啟動Client

③ Java網路編程從入門到精通(4):DNS緩存

在通過DNS查找域名的過程中 可能會經過多台中間DNS伺服器才能找到指定的域名 因此 在DNS伺服器上查找域名是非常昂貴的操作 在Java中為了緩解這個問題 提供了DNS緩存 當InetAddress類第一次使用某個域名(如)創建InetAddress對象後 JVM就會將這個域名和它從DNS上獲得的信息(如IP地址)都保存在DNS緩存中 當下一次InetAddress類再使用這個域名時 就直接從DNS緩存里獲得所需的信息 而無需再訪問DNS伺服器

DNS緩存在默認時將永遠保留曾經訪問過的域名信息 但我們可以修改這個默認值 一般有兩種方法可以修改這個默認值

在程序中通過java security Security setProperty方法設置安全屬性nel的值(單位 秒) 如下面的代碼將緩存超時設為 秒

java security Security setProperty( nel );

設置java security文件中的neorkaddresl屬性 假設JDK的安裝目錄是C jdk 那麼java security文件位於c jdk jrelibsecurity目錄中 打開這個文件 找到nel屬性 並將這個屬性值設為相應的緩存超時(單位 秒)

如果將nel屬性值設為 那麼DNS緩存數據將永遠不會釋放 下面的代碼演示了使用和不使用DNS緩存所產生效果

package mynet;import *;publicclass MyDNS{publicstaticvoidmain(String[]args)throwsException{//args[ ]:本機名args[ ] 緩沖時間if(args length< )return;java security Security setProperty( nel args[ ]);longtime=System currentTimeMillis();InetAddressaddresses []=InetAddress getAllByName(args[ ]);System out println( addresses : +String valueOf(System currentTimeMillis() time)+ 毫秒 );for(InetAddressaddress:addresses )System out println(address);System out print( 按任意鍵繼續 );System in read();time=System currentTimeMillis();InetAddressaddresses []=InetAddress getAllByName(args[ ]);System out println( addresses : +String valueOf(System currentTimeMillis() time)+ 毫秒 );for(InetAddressaddress:addresses )System out println(address);}}

在上面的代碼中設置了DNS緩存超時(通過args[ ]參數) 用戶可以通過命令行參數將這個值傳入MyDNS中 這個程序首先使用getAllByName建立一個InetAddress數組 然後通過System in read使程序暫停 當用戶等待一段時間後 可以按任意鍵繼續 並使用同一個域名(args[ ])再建立一個InetAddress數組 如果用戶等待的這段時間比DNS緩存超時小 那麼無論情況如何變化 addresses 和addresses 數組中的元素是一樣的 並且創建addresses 數組所花費的時間一般為 毫秒(小於 毫秒後 Java無法獲得更精確的時間)

測試

執行如下命令(將DNS緩存超時設為 秒)

java mynet MyDNS

運行結果 (在 秒之內按任意鍵)

addresses : 毫秒/ 按任意鍵繼續addresses : 毫秒/

運行結果 (在 秒後按任意鍵)

addresses : 毫秒/ 按任意鍵繼續addresses : 毫秒/

在上面的測試中可能出現兩個運行結果 如果在出現 按任意鍵繼續… 後 在 秒之內按任意鍵繼續後 就會得到運行結果 從這個結果可以看出 addresses 所用的時間為 毫秒 也就是說 addresses 並未真正訪問DNS伺服器 而是直接從內存中的DNS緩存得到的數據 當在 秒後按任意鍵繼續後 就會得到運行結果 這時 內存中的DNS緩存中的數據已經釋放 所以addresses 還得再訪問DNS伺服器 因此 addresses 的時間是 毫秒(addresses 和addresses 後面的毫秒數可能在不同的環境下的值不一樣 但一般情況下 運行結果 的addresses 的值為 或是一個接近 的數 如 運行結果 的addresses 的值一般會和addresses 的值很接近 或是一個遠比 大的數 如 )

測試

執行如下命令(ComputerName為本機的計算機名 DNS緩存超時設為永不過期[ ])

java mynet MyDNS ComputerName

運行結果(按任意鍵繼續之前 將 刪除)

addresses : 毫秒myuniverse/ myuniverse/ 按任意鍵繼續addresses : 毫秒myuniverse/ myuniverse/

從上面的測試可以看出 將DNS緩存設為永不過期後 無論過多少時間 按任意鍵後 addresses 任然得到了兩個IP地址( 和 ) 而且addresses 的時間是 毫秒 但在這時 已經被刪除 因此可以判斷 addresses 是從DNS緩存中得到的數據 如果運行如下的命令 並在 秒後按任意鍵繼續後 addresses 就會只剩下一個IP地址( )

java mynet MyDNS ComputerName

如果域名在DNS伺服器上不存在 那麼客戶端在進行一段時間的嘗試後(平均為 秒) 就會拋出一個UnknownHostException異常 為了讓下一次訪問這個域名時不再等待 DNS緩存將這個錯誤信息也保存了起來 也就是說 只有第一次訪問錯誤域名時才進行 稱左右的嘗試 以後再訪問這個域名時將直接拋出UnknownHostException異常 而無需再等待 秒鍾

訪問域名失敗的原因可能是這個域名真的不存在 也可能是因為DNS伺服器或是其他的硬體或軟體的臨時故障 因此 一般不能將這個域名錯誤信息一直保留 在Java中可以通過neorkaddresl屬性設置保留這些信息的時間 這個屬性的默認值是 秒 它也可以通過java security Security setProperty方法或java security文件來設置 下面的代碼演示了neorkaddresl屬性的用法

package mynet;import *;publicclass MyDNS {publicstaticvoidmain(String[]args)throwsException{java security Security setProperty( neorkaddresl );longtime= ;try{time=System currentTimeMillis();InetAddress getByName( );}catch(Exceptione){System out println( 不存在!address : +String valueOf(System currentTimeMillis() time)+ 毫秒 );}//Thread sleep( );//延遲 秒try{time=System currentTimeMillis();InetAddress getByName( );}catch(Exceptione){System out println( 不存在!address : +String valueOf(System currentTimeMillis() time)+ 毫秒 );}}}

在上面的代碼中將neorkaddresl屬性值設為 秒 這個程序分別測試了address 和address 訪問(這是個不存在的域名 讀者可以將其換成任何不存在的域名)後 用了多長時間拋出UnknownHostException異常

運行結果

不存在!address : 毫秒不存在!address : 毫秒

我們從上面的運行結果可以看出 address 使用了 毫秒就拋出了異常 因此 可以斷定address 是從DNS緩存里獲得了域名不可訪問的信息 所以就直接拋出了UnknowHostException異常 如果將上面代碼中的延遲代碼的注釋去掉 那麼可能得到如下的運行結果

不存在!address : 毫秒不存在!address : 毫秒

從上面的運行結果可以看出 在第 秒時 DNS緩存中的數據已經被釋放 因此 address 仍需要訪問DNS伺服器才能知道是不可訪問的域名

在使用DNS緩存時有兩點需要注意

可以根據實際情況來設置nel屬性的值 一般將這個屬性的值設為 但如果訪問的是動態映射的域名(如使用動態域名服務將域名映射成ADSL的動態IP) 就可能產生IP地址變化後 客戶端得到的還是原來的IP地址的情況

lishixin/Article/program/Java/hx/201311/11147

④ GitHub上面有哪些經典的java框架源碼

⑤ Java網路編程從入門到精通(33):非阻塞I/O的緩沖區(Buffer)

如果將同步I/O方式下的數據傳輸比做數據傳輸的零星方式(這里的零星是指在數據傳輸的過程中是以零星的位元組方式進行的) 那麼就可以將非阻塞I/O方式下的數據傳輸比做數據傳輸的集裝箱方式(在位元組和低層數據傳輸之間 多了一層緩沖區 因此 可以將緩沖區看做是裝載位元組的集裝箱) 大家可以想像 如果我們要運送比較少的貨物 用集裝箱好象有點不太合算 而如果要運送上百噸的貨物 用集裝箱來運送的成本會更低 在數據傳輸過程中也是一樣 如果數據量很小時 使用同步I/O方式會更適合 如果數據量很大時(一般以G為單位) 使用非阻塞I/O方式的效率會更高 因此 從理論上說 數據量越大 使用非阻塞I/O方式的單位成本就會越低 產生這種結果的原因和緩沖區的一些特性有著直接的關系 在本節中 將對緩沖區的一些主要特性進行講解 使讀者可以充分理解緩沖區的概念沖森 並能通過緩沖區來提高程序的執行效率

創建緩沖區

Java提供了七個基本的緩沖區 分別由七個類來擾判拍管理 它們都可以在java nio包中找到 這七個類如下所示

ByteBuffer

ShortBuffer

IntBuffer

CharBuffer

FloatBuffer

DoubleBuffer

LongBuffer

這七個類中的方法類似 只是它們的返回值或參數和相應的簡單類型相對應 如ByteBuffer類的get方法返回了byte類型的數據 而put方法需要一個byte類型的參數 在CharBuffer類中的get和put方法返回和傳遞的數據類型就是char 這七個類都沒有public構造方法 因此 它們不能通過new來創建相應的對象實例 這些類都可以通過兩種方式來創建相應的對象實例

通過靜態方法allocate來創建緩沖區

這七類都有一個靜態的allocate方法 通過這個方法可以創建有最大容量限制的緩沖區對象 allocate的定義如下

ByteBuffer類中的allocate方法

(intcapacity)

IntBuffer類中的allocate方法

publicstaticIntBufferallocate(intcapacity)

其他五個緩沖區類中的allocate 方法定義和上面的定義類似 只是返回值的類型是相應的緩沖區緩羨類

allocate方法有一個參數capacity 用來指定緩沖區容量的最大值 capacity的不能小於 否則會拋出一個IllegalArgumentException異常 使用allocate來創建緩沖區 並不是一下子就分配給緩沖區capacity大小的空間 而是根據緩沖區中存儲數據的情況來動態分配緩沖區的大小(實際上 在低層Java採用了數據結構中的堆來管理緩沖區的大小) 因此 這個capacity可以是一個很大的值 如 * ( M) allocate的使用方法如下

ByteBufferbyteBuffer=ByteBuffer allocate( );IntBufferintBuffer=IntBuffer allocate( );

在使用allocate創建緩沖區時應用注意 capacity的含義隨著緩沖區的不同而不同 如創建位元組緩沖區時 capacity指的是位元組數 而在創建整型(int)緩沖區時 capacity指的是int型值的數目 如果轉換成字數 capacity的值應該乘 如上面代碼中的intBuffer緩沖區最大可容納的位元組數是 * = 個

通過靜態方法wrap來創建緩沖區

使用allocate方法可以創建一個空的緩沖區 而wrap方法可以利用已經存在的數據來創建緩沖區 wrap方法可以將數組直接轉換成相應類型的緩沖區 wrap方法有兩種重載形式 它們的定義如下

ByteBuffer類中的wrap方法

publicstaticByteBufferwrap(byte[]array)publicstaticByteBufferwrap(byte[]array intoffset intlength)

IntBuffer類中的wrap方法

publicstaticIntBufferwrap(byte[]array)publicstaticIntBufferwrap(byte[]array intoffset intlength)

其他五個緩沖區類中的wrap 方法定義和上面的定義類似 只是返回值的類型是相應的緩沖區類

在wrap方法中的array參數是要轉換的數組(如果是其他的緩沖區類 數組的類型就是相應的簡單類型 如IntBuffer類中的wrap方法的array就是int[]類型) offset是要轉換的子數組的偏移量 也就是子數組在array中的開始索引 length是要轉換的子數組的長度 利用後兩個參數可以將array數組中的一部分轉換成緩沖區對象 它們的使用方法如下

byte[]myByte=newbyte[]{ };int[]myInt=newint[]{ };ByteBufferbyteBuffer=ByteBuffer wrap(myByte);IntBufferintBuffer=IntBuffer wrap(myInt );

可以通過緩沖區類的capacity方法來得到緩沖區的大小 capacity方法的定義如下

publicfinalintcapacity()

如果使用allocate方法來創建緩沖區 capacity方法的返回值就是capacity參數的值 而使用wrap方法來創建緩沖區 capacity方法的返回值是array數組的長度 但要注意 使用wrap來轉換array的字數組時 capacity的長度仍然是原數組的長度 如上面代碼中的intBuffer緩沖區的capacity值是 而不是

除了可以將數組轉換成緩沖區外 也可以通過緩沖區類的array方法將緩沖區轉換成相應類型的數組 IntBuffer類的array方法的定義方法如下(其他緩沖區類的array的定義類似)

publicfinalint[]array()

下面的代碼演示了如何使用array方法將緩沖區轉換成相應類型的數組

int[]myInt=newint[]{ };IntBufferintBuffer=IntBuffer wrap(myInt );for(intv:intBuffer array()) System out print(v+ );

在執行上面代碼後 我們發現輸出的結果是 而不是 這說明在將子數組轉換成緩沖區的過程中實際上是將整個數組轉換成了緩沖區 這就是用wrap包裝子數組後 capacity的值仍然是原數組長度的真正原因 在使用array方法時應注意 在以下兩種緩沖區中不能使用array方法

只讀的緩沖區如果使用只讀緩沖區的array方法 將會拋出一個ReadOnlyBufferException異常

使用allocateDirect方法創建的緩沖區

如果調用這種緩沖區中的array方法 將會拋出一個UnsupportedOperationException異常

可以通過緩沖區類的hasArray方法來判斷這個緩沖區是否可以使用array方法 如果返回true 則說明這個緩沖區可以使用array方法 否則 使用array方法將會拋出上述的兩種異常之一

注意 使用array方法返回的數組並不是緩沖區數據的副本 被返回的數組實際上就是緩沖區中的數據 也就是說 array方法只返回了緩沖區數據的引用 當數組中的數據被修改後 緩沖區中的數據也會被修改 返之也是如此 關於這方面內容將在下一節 讀寫緩沖區中的數據 中詳細講解

在上述的七個緩沖區類中 ByteBuffer類和CharBuffer類各自還有另外一種方法來創建緩沖區對象

ByteBuffer類

可以通過ByteBuffer類的allocateDirect方法來創建ByteBuffer對象 allocateDirect方法的定義如下

Direct(intcapacity)

使用allocateDirect方法可以一次性分配capacity大小的連續位元組空間 通過allocateDirect方法來創建具有連續空間的ByteBuffer對象雖然可以在一定程度上提高效率 但這種方式並不是平台獨立的 也就是說 在一些操作系統平台上使用allocateDirect方法來創建ByteBuffer對象會使效率大幅度提高 而在另一些操作系統平台上 性能會表現得非常差 而且allocateDirect方法需要較長的時間來分配內存空間 在釋放空間時也較慢 因此 在使用allocateDirect方法時應謹慎

通過isDirect方法可以判斷緩沖區對象(其他的緩沖區類也有isDirect方法 因為 ByteBuffer對象可以轉換成其他的緩沖區對象 這部分內容將在後面講解)是用哪種方式創建的 如果isDirect方法返回true 則這個緩沖區對象是用allocateDirect方法創建的 否則 就是用其他方法創建的緩沖區對象

CharBuffer類

我們可以發現 上述的七種緩沖區中並沒有字元串緩沖區 而字元串在程序中卻是最常用的一種數據類型 不過不要擔心 雖然java nio包中並未提供字元串緩沖區 但卻可以將字元串轉換成字元緩沖區(就是CharBuffer對象) 在CharBuffer類中的wrap方法除了上述的兩種重載形式外 又多了兩種重載形式 它們的定義如下

publicstaticCharBufferwrap(CharSequencecsq)publicstaticCharBufferwrap(CharSequencecsq intstart intend)

其中csq參數表示要轉換的字元串 但我們注意到csq的類型並不是String 而是CharSequence CharSequence類Java中四個可以表示字元串的類的父類 這四個類是String StringBuffer StringBuilder和CharBuffer(大家要注意 StringBuffer和本節講的緩沖區類一點關系都沒有 這個類在java lang包中) 也就是說 CharBuffer類的wrap方法可以將這四個類的對象轉換成CharBuffer對象

另外兩個參數start和end分別是子字元串的開始索引和結束索引的下一個位置 如將字元串 中的 轉換成CharBuffer對象的語句如下

CharBuffercb=CharBuffer wrap( );

下面的代碼演示了如何使用wrap方法將不同形式的字元串轉換成CharBuffer對象

lishixin/Article/program/Java/hx/201311/26505

⑥ Java網路編程從入門到精通(5):使用InetAddress類的getHostName方法獲得域

該方法可以得到遠程主機的域名 也可以得到本機名 getHostName方法的定義如下

publicStringgetHostName()

下面是三種創建InetAddress對象的方式 在這三種方式中 getHostName返回的值是不同的

使用getLocalHost方法創建InetAddress對象

如果InetAddress對象是用getLocalHost方法創建的 getHostName返回的是本機名 如下面的代碼所示

InetAddressaddress=InetAddress getLocalHost();System out println(address getHostName());//輸出本機名

使用域名創建InetAddress對象

用域名作為getByName和getAllByName方法的參數調用這兩個方法後 系統會自動記住這個域名 當調用getHostName方法時 就無需再訪問DNS伺服器 而是直接將這個域名返回 如下面的代碼所示

InetAddressaddress=InetAddress getByName( );System out println(address getHostName());//無需訪問DNS伺服器 直接返回域名

使用IP地址創建InetAddress對象

使用IP地址創建InetAddress對象時(getByName getAllByName和getByAddress方法都可以通過IP地址創建InetAddress對象) 並不需要訪問DNS伺服器 因此 通過DNS伺服器查找域名的工作就由getHostName方法來完成 如果這個IP地址不存在或DNS伺服器不允許進行IP地址和域名的映射 getHostName方法就直接返回這個IP地址 如下面的代碼所示

InetAddressaddress=InetAddress getByName( );System out println(address getHostName());//需要訪問DNS伺服器才能得到域名InetAddressaddress=InetAddress getByName( );//IP地址不存在System out println(address getHostName());//直接返回IP地址

從上面的三種情況可以看出 只有通過使用IP地址創建的InetAddress對象調用getHostName方法時才訪問DNS伺服器 在其他情況 getHostName方法並不會訪問DNS伺服器 而是直接將域名或本機名返回 下面的代碼演示了在不同情況下如何使用getHostName方法 並計算了各種情況所需的毫秒數

package mynet;import *;publicclass DomainName{publicstaticvoidmain(String[]args)throwsException{longtime= ;//得到本機名InetAddressaddress =InetAddress getLocalHost();System out println( 本機名 +address getHostName());//直接返回域名InetAddressaddress =InetAddress getByName( );time=System currentTimeMillis();System out print( 直接得到域名 +address getHostName());System out println( 所用時間 +String valueOf(System currentTimeMillis() time)+ 毫秒 );//通過DNS查找域名InetAddressaddress =InetAddress getByName( ); System out println( address : +address );//域名為空time=System currentTimeMillis();System out print( 通過DNS查找域名 +address getHostName());System out println( 所用時間 +String valueOf(System currentTimeMillis() time)+ 毫秒 ); System out println( address : +address );//同時輸出域名和IP地址}}

運行結果

本機名 ComputerName直接得到域名 所用時間 毫秒address :/ 通過DNS查找域名 bigip o所用時間 毫秒address :bigip o/

lishixin/Article/program/Java/hx/201311/26413

閱讀全文

與java網路編程精解源代碼相關的資料

熱點內容
程序員畢設可以攻哪個方向 瀏覽:427
毛絨玩具怎麼壓縮 瀏覽:378
拖拉式編程教學視頻 瀏覽:793
伺服器壞了硬碟數據如何取出 瀏覽:602
體積加密度等於質量嗎 瀏覽:608
如何執行命令 瀏覽:859
速賣通指標源碼 瀏覽:179
linux切換root登錄 瀏覽:925
什麼是有效的伺服器地址 瀏覽:825
交通銀行app如何信用卡額度查詢 瀏覽:479
asp程序員收入 瀏覽:334
無線有密碼顯示未加密 瀏覽:212
檢查伺服器地址命令 瀏覽:599
編譯過程和解釋過程的圖表形式 瀏覽:837
文明重啟如何弄自己的伺服器免費 瀏覽:912
伺服器許可權不足如何解決 瀏覽:373
少兒編程樂高主要是學什麼 瀏覽:674
張家口人社app如何實名認證 瀏覽:296
淘寶圖片怎麼設置加密 瀏覽:314
pdf拼接器 瀏覽:786