Java基礎---網絡編程

第一講??? ?概述?

1、網絡模型:OSI參考模型和TCP/IP參考模型

圖示:

??????? 一般來說開發處于傳輸層和網際層,應用層為:FTP和HTTP協議等,傳輸層為:UDP和TCP等,網際層為:IP。

??????? 通常用戶操作的是應用層,而編程人員需要做的是傳輸層和網際層,用戶在應用層操作的數據,經過逐層封包,最后到物理層發送到另一個模型中,再進行逐層解包,圖示為:

?

2、網絡通信三要素:IP地址,端口號,傳輸協議

A、IP地址

??????? a、它是網絡中的設備標識

??????? b、不易記憶,可用主機名表示,兩者存在映射關系

??????? c、本機回環地址:127.0.0.1,主機名為:localhost。

IP地址:java中對應的是InetAddress類,存在于java.net包中。

InetAddress類:

???? (一)無構造函數,可通過getLocalHost()方法獲取InetAddress對象,此方法是靜態的,返回本類對象。

??????????????????InetAddress i = InetAddress.getLocalHost();

???? (二)方法:

??????????????? 1)static InetAddress getByName(String host):獲取指定主機的IP和主機名。(最好用ip地址去獲取,主機名需要解析)

??????????????? 2)static InetAddress[] getAllByName(String host):在給定主機名的情況下,根據系統上配置的名稱服務返回IP地址所組成的數組。返回對象不唯一時,用此方法。

??????????????? 3)String getHostAddress():返回IP地址字符串文本形式,以IP地址為主。

??????????????? 4)String getHostName():返回IP地址主機名。

???? (三)如何獲取任意一臺主機的IP地址對象:

??????????????? 1)功能:返回InetAddress對象

??????????????? 2)對于任意主機,需要指定傳入主機名的參數

注意:如果IP地址和對應的主機名,這種映射關系沒有在網絡上,就不會解析成功,返回的還是指定的IP。

示例:

[java]?view plaincopy
  1. import?java.net.*;??
  2. class?IPDemo???
  3. {??
  4. ????public?static?void?main(String[]?args)throws?Exception???
  5. ????{??
  6. ????????//獲取本類對象??
  7. ????????InetAddress?ia=InetAddress.getLocalHost();??
  8. ??????????
  9. ????????//ip??
  10. ????????String?address=ia.getHostAddress();??
  11. ????????//主機名??
  12. ????????String?name=ia.getHostName();??
  13. ????????System.out.println("IP="+address+"\tname="+name);??
  14. ??
  15. ????????//獲取指定主機的ip信息??
  16. ????????InetAddress?i=InetAddress.getByName("192.168.1.175");??
  17. ??
  18. ????????String?add=i.getHostAddress();??
  19. ????????String?na=i.getHostName();??
  20. ????????System.out.println("addIP="+add+"\tiname="+na);??
  21. ??
  22. ????????//獲取指定主機名的ip信息??
  23. ????????InetAddress[]?baidu=InetAddress.getAllByName("www.baidu.com");??
  24. ????????for?(InetAddress?b?:baidu)??
  25. ????????{??
  26. ????????????String?baddress=b.getHostAddress();??
  27. ????????????String?bname=b.getHostName();??
  28. ????????????System.out.println("baiduIP="+baddress+"\tbaiduname="+bname);??
  29. ????????}??
  30. ????}??
  31. }??

B、端口號:

??????? a、用于標識進程的邏輯地址,不用進程的標識。

??????? b、有效端口:0 ~65535,系統使用或保留的端口是:0~ 1024。

C、傳輸協議:

??????? 即通信規則,包含TCP和UDP協議

UDP

??????? 是面向無連接,明確了對方的端口,無論在不在網上,只管傳輸,不在就會丟失數據。只求速度,應用于網絡視頻會議和聊天等應用程序中。

協議特點:

???????? a、面向無連接,即將數據及源和目的封裝成數據包中,不建立鏈接的發送

???????? b、每個數據包的大小限制在64K之內

???????? c、因無連接,是不可靠的協議

???????? d、不建立連接,速度快。

TCP

??????? 是面向連接的,必須連接成功才能傳輸數據,應用于下載等程序上

協議特點:

???????? a、面向連接,在建立連接后,形成傳輸數據的通道

???????? b、在連接中進行大數據量的傳輸

?????????c、通過三次握手完成連接,是可靠的協議

???????? d、必須建立連接,效率稍慢

三次握手:第一次本方發送請求,第二次對方確認連接,第三次本方再次確認連接成功。

3、通信的步驟:

??????? 1)找到IP地址

??????? 2)數據要發送到對象指定應用程序,為標識這些應用程序,所以給這些網絡應用程序都用數字標識,為方便稱呼這個數字,叫做端口,即邏輯端口。

??????? 3)定義通信規則,稱之為協議。國際組織定義了通用協議,即TCP/IP。

注意:必須要有數字標識才能將數據發送到應用程序上。

?

第二講?????傳輸協議

一、Socket

??????? 1、它被稱之為插座,相當于港口一樣,是網絡服務提供的一種機制。

??????? 2、通信兩端都要有Socket,才能建立服務。

??????? 3、網絡通信其實就是Socket間的通信,數據在兩個Socket間通過IO傳輸。

?

二、UDP傳輸

1、通過類DatagramSocket,此類表示用發送和接收數據包的套接字,即Socket。

2、方法:

??????? 1)創建?UDPSocket發送服務對象:

????????????? DatagramSocket(),不指定端口。DatagramSocket(int port),指定端口。

??????? 2)發送:void send(DatagramPacket p)

??????? 3)接收:void receive(DatagramPacket p)

???????其中DatagramPacket:數據報包用來實現無連接包投遞服務的,每條報文僅根據該包中包含的信息從一臺機器路由到另一臺機器中。凡是帶地址(InetAddress)的都是用于發送包的。

3、步驟

??????? 1)發送數據:

????????????? a、建立UDPSocket服務,在此無需指定端口,也可以將端口加入。如果不指定的話,系統會隨機分配一個端口,如第一次運行時端口為1093,那么第二次就會順延為1094,再運行會一直順延,因為之前的端口還沒有得到釋放,所以會順延端口號值。

????????????? b、提供數據,并將數據封裝到數據包中

????????????? c、通過socket服務的發送功能,將數據包發送出去

????????????? d、關閉資源

??????? 2)接收數據:

????????????? a、定義UDPSocket服務。通常會監聽一個端口,其實就是給這個接收網路應用程序定義數字標識,方便于明確哪些數據過來該應用程序可以處理。

????????????? b、定義一個數據包,用來存儲接收到的字節數據,因為數據包對象中有更多功能可以提取字節數據中的不同數據信息。

????????????? c、通過socket服務的receive方法接收到的數據存入已定義好的數據包中傷感的句子

????????????? d、通過數據包對象的特有功能,將這些不同的數據取出,打印在控制臺上

??????????????e、關閉資源

????????在定義接收數據的方法中,仍會在DatagramSocket構造函數中傳入DatagramPacket的參數,這是因為收到的數據太多,需要解析,通過將數據封裝成對象,易于解析,所以需要傳入參數。

注意:

??????? 1、發送端與接收端是兩個獨立的運行程序。

????????2、在發送端,要在數據包對象中明確目的地IP及端口。

??????? 3、在接收端,要指定監聽的端口。

示例:

[java]?view plaincopy
  1. /*?
  2. udp發送端:?
  3. 需求:通過udp傳輸方式,將一段文字數據發送出去。?
  4. */??
  5. ??
  6. import?java.net.*;??
  7. class?UdpSend???
  8. {??
  9. ????public?static?void?main(String[]?args)throws?Exception???
  10. ????{??
  11. ????????//1、創建udp服務。通過DatagramSocket對象??
  12. ????????DatagramSocket?ds=new?DatagramSocket();??
  13. ????????//2、確定數據,并封裝成數據包。DatagramPacket(byte[]?buf,?int?length,?InetAddress?address,?int?port)???
  14. ????????byte[]?buf="udp?shi?shen?ma".getBytes();??
  15. ????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.175"),10000);??
  16. ??
  17. ????????//3、通過Socket服務,將已有的數據包發送出去。通過send方法。??
  18. ????????ds.send(dp);??
  19. ????????//4、關閉資源??
  20. ????????ds.close();??
  21. ????}??
  22. }??
  23. ??
  24. /*?
  25. udp接收端?
  26. 需求:定義一個應用程序,用于接收udp協議傳輸的數據并處理。?
  27. */??
  28. ??
  29. class?UdpReceive??
  30. {??
  31. ????public?static?void?main(String[]?args)throws?Exception??
  32. ????{??
  33. ????????//1、創建udp?Socket服務,建立端點??
  34. ????????//DatagramSocket?ds=new?DatagramSocket(10000);??
  35. ??????????
  36. ????????//一直處于接收狀態??
  37. ????????while(true)??
  38. ????????{??
  39. ????????????//1、創建udp?Socket服務,建立端點??
  40. ????????????DatagramSocket?ds=new?DatagramSocket(10000);??
  41. ????????????//2、定義數據包。用于存儲數據??
  42. ????????????byte[]?buf=new?byte[1024];??
  43. ????????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length);??
  44. ????????????//3、通過Socket服務的receive方法將接收到的數據存入數據包中??
  45. ????????????ds.receive(dp);//阻塞式方法??
  46. ????????????//4、通過數據包的方法獲取其中的數據??
  47. ????????????String?ip=dp.getAddress().getHostName();??
  48. ????????????String?data=new?String(dp.getData(),0,dp.getLength());??
  49. ????????????int?port=dp.getPort();??
  50. ????????????System.out.println(ip+"::"+data+"::"+port);??
  51. ????????????//5、關閉資源??
  52. ????????????ds.close();??
  53. ????????}??
  54. ????????//5、關閉資源??
  55. ????????//ds.close();??
  56. ????}??
  57. }??

練習一

[java]?view plaincopy
  1. /*?
  2. 用鍵盤錄入的方式,來發送數據?
  3. */??
  4. ??
  5. import?java.net.*;??
  6. import?java.io.*;??
  7. //UDP?發送端??
  8. class?UdpSend????
  9. {??
  10. ????public?static?void?main(String[]?args)throws?Exception??
  11. ????{??
  12. ????????//1、創建udp?Socket服務??
  13. ????????DatagramSocket?ds=new?DatagramSocket(9999);??
  14. ????????//2、確定數據,從鍵盤錄入,并把鍵盤錄入的數據封裝成數據包??
  15. ????????DatagramPacket?dp=null;??
  16. ????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??
  17. ????????String?line=null;??
  18. ????????while((line=br.readLine())!=null)??
  19. ????????{??
  20. ????????????byte[]?buf=line.getBytes();??
  21. ????????????dp=new?DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10000);??
  22. ????????????//3、通過Socket服務,將已有的數據包發送出去??
  23. ????????????ds.send(dp);??
  24. ????????????if?("886".equals(line))??
  25. ????????????{??
  26. ????????????????break;??
  27. ????????????}??
  28. ????????}??
  29. ????????//4、關閉資源??
  30. ????????ds.close();??
  31. ??????????
  32. ????}??
  33. }??
  34. ??
  35. //UDP?接收端??
  36. class?UdpReceive??
  37. {??
  38. ????public?static?void?main(String[]?args)throws?Exception??
  39. ????{??
  40. ????????//1、創建udp?Socket服務??
  41. ????????DatagramSocket?ds=new?DatagramSocket(10000);??
  42. ????????//一直處于接收狀態??
  43. ????????while?(true)??
  44. ????????{??
  45. ????????????//2、定義數據包,用于存儲數據??
  46. ????????????byte[]?buf=new?byte[1024];??
  47. ????????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length);??
  48. ????????????//3、通過Socket服務,將數據接收并存儲進數據包中??
  49. ????????????ds.receive(dp);??
  50. ????????????//4、通過數據包的方法獲取其中的數據??
  51. ????????????String?ip=dp.getAddress().getHostAddress();??
  52. ????????????String?data=new?String(dp.getData(),0,dp.getLength());??
  53. ????????????int?port=dp.getPort();??
  54. ??
  55. ????????????System.out.println("IP:"+ip+"=="+data);??
  56. ????????}??
  57. ????????//5、關閉資源??
  58. ????????//ds.close();??
  59. ????}??
  60. }?????

練習二

[java]?view plaincopy
  1. /*?
  2. 編寫一個聊天程序。?
  3. 有收數據的部分,和發數據的部分。?
  4. 這兩部分需要同時執行。?
  5. 那就需要用到多線程技術。?
  6. 一個線程控制收,一個線程控制發。?
  7. ?
  8. 因為收和發動作是不一致的,所以要定義兩個run方法。?
  9. 而且這個兩個方法要封裝到不同的類中。?
  10. ?
  11. */??
  12. //Udp發送線程??
  13. ??
  14. import?java.net.*;??
  15. import?java.io.*;??
  16. ??
  17. class?UdpSend?implements?Runnable??
  18. {??
  19. ????//定義Socket服務引用??
  20. ????private?DatagramSocket?ds;??
  21. ????UdpSend(DatagramSocket?ds)??
  22. ????{??
  23. ????????this.ds=ds;??
  24. ????}??
  25. ????//復寫run方法??
  26. ????public?void?run()??
  27. ????{??
  28. ????????try??
  29. ????????{??
  30. ????????????//2、確定數據,從鍵盤錄入,并把鍵盤錄入的數據封裝成數據包??
  31. ????????????DatagramPacket?dp=null;??
  32. ????????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??
  33. ????????????String?line=null;??
  34. ????????????while((line=br.readLine())!=null)??
  35. ????????????{??
  36. ????????????????byte[]?buf=line.getBytes();??
  37. ????????????????dp=new?DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10000);??
  38. ????????????????//3、通過Socket服務,將已有的數據包發送出去??
  39. ????????????????ds.send(dp);??
  40. ????????????????if?("886".equals(line))??
  41. ????????????????{??
  42. ????????????????????break;??
  43. ????????????????}??
  44. ????????????}??
  45. ????????????//4、關閉資源??
  46. ????????????ds.close();??
  47. ????????}??
  48. ????????catch?(Exception?e)??
  49. ????????{??
  50. ????????????throw?new?RuntimeException("發送數據失敗");??
  51. ????????}?????????
  52. ????}??
  53. }??
  54. ??
  55. //Udp接收線程??
  56. class?UdpReceive?implements?Runnable??
  57. {??
  58. ????//定義Socket服務引用??
  59. ????private?DatagramSocket?ds;??
  60. ????UdpReceive(DatagramSocket?ds)??
  61. ????{??
  62. ????????this.ds=ds;??
  63. ????}??
  64. ????//復寫run方法??
  65. ????public?void?run()??
  66. ????{??
  67. ????????try??
  68. ????????{??
  69. ????????????//一直處于接收狀態??
  70. ????????????while?(true)??
  71. ????????????{??
  72. ????????????????//2、定義數據包,用于存儲數據??
  73. ????????????????byte[]?buf=new?byte[1024];??
  74. ????????????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length);??
  75. ????????????????//3、通過Socket服務,將數據接收并存儲進數據包中??
  76. ????????????????ds.receive(dp);??
  77. ????????????????//4、通過數據包的方法獲取其中的數據??
  78. ????????????????String?ip=dp.getAddress().getHostAddress();??
  79. ????????????????String?data=new?String(dp.getData(),0,dp.getLength());??
  80. ????????????????int?port=dp.getPort();??
  81. ??
  82. ????????????????System.out.println("IP:"+ip+"=="+data);??
  83. ????????????}??
  84. ????????????//5、關閉資源??
  85. ????????????//ds.close();??
  86. ????????}??
  87. ????????catch?(Exception?e)??
  88. ????????{??
  89. ????????????throw?new?RuntimeException("接收端接收數據失敗");??
  90. ????????}??
  91. ????}??
  92. }??
  93. ??
  94. class?UdpChatDemo??
  95. {??
  96. ????public?static?void?main(String[]?args)throws?Exception??
  97. ????{??
  98. ????????new?Thread(new?UdpSend(new?DatagramSocket())).start();??
  99. ????????new?Thread(new?UdpReceive(new?DatagramSocket(10000))).start();??
  100. ????}??
  101. }??

三、TCP傳輸

1、TCP分客戶端和服務端。客戶端對應的對象是Socket,服務端對應的對象是ServerSocket。

2、方法:

??????? 1)創建客戶端對象:

??????????????Socket():創建空參數的客戶端對象,一般用于服務端接收數據

????????????? Socket(String host,int port),指定要接收的IP地址和端口號淘寶開店

??????? 2)創建服務端對象:ServerSocket(int port):指定接收的客戶端的端口

??????? 3)Socket accept():監聽并接受到此套接字的連接

??????? 4)void shutdownInput():此套接字的輸入流至于“流的末尾”

??????? 5)void shutdownOutput():禁用此套接字的輸出流

??????? 6)InputStream getInputStream():返回此套接字的輸入流,Socket對象調用

??????? 7)OutputStream getOutputStream():返回套接字的輸出流,Socket對象調用

3、基本思路

客戶端:

??????? 1)客戶端需要明確服務器的ip地址以及端口,這樣才可以去試著建立連接,如果連接失敗,會出現異常。

??????? 2)連接成功,說明客戶端與服務端建立了通道,那么通過IO流就可以進行數據的傳輸,而Socket對象已經提供了輸入流和輸出流對象,通過getInputStream(),getOutputStream()獲取即可。

??????? 3)與服務端通訊結束后,關閉Socket。

服務端:

??????? 1)服務端需要明確它要處理的數據是從哪個端口進入的。

??????? 2)當有客戶端訪問時,要明確是哪個客戶端,可通過accept()獲取已連接的客戶端對象,并通過該對象與客戶端通過IO流進行數據傳輸。

??????? 3)當該客戶端訪問結束,關閉該客戶端。

4、步驟

客戶端:

??????? 通過查閱Socket對象的API文檔,發現在該對象在建立時,就可去連接指定主機,因為TCP是面向連接的,所以在建立Socket服務時,就要有服務端存在,并連接成功,形成通路后,再通過該通道進行數據的傳輸。

?????????1)創建Socket服務,并指定要連接的主機端口。通路一建立,就會產生Socket流(包括輸入流和輸出流),通過方法獲取

???????? 2)為了發送數據,應獲取Socket中的輸出流,如果要接收服務端的反饋信息,還需要獲取Socket的輸入流

???????? 3)通過輸出流的write()方法將要發送的數據寫入到流中

???????? 4)關閉Socket流資源

服務端:

??????? 服務器套接字等待請求通過網絡傳入。它基于該請求執行某些操作,然后可能向請求者返回結果。需監聽一個端口。

?????????1)建立服務端的Socket服務,并監聽一個端口。通過ServerSocet帶端口參數的構造函數

???????? 2)獲取連接過來的客戶對象,通過ServerSocket的accept()方法,此方法是阻塞式的,如果服務端沒有連接到就會一直等待

???????? 3)客戶端如果發過來數據,則服務端要使用對應的客戶端對象,并獲取到該客戶端對象的讀取流讀取發過來的數據,并輸出到指定目的地。

???????? 4)關閉服務端(可選)。一般服務端是常開的,因為在實際應用中,隨時有客戶端在請求連接和服務。但這里需要定時關閉客戶端對象流,避免某一個客戶端長時間占用服務器端。

示例:

[java]?view plaincopy
  1. /*?
  2. 需求:客戶端給服務端發送數據,服務端收到后,給客戶端反饋信息。?
  3. */??
  4. //客戶端??
  5. import?java.net.*;??
  6. import?java.io.*;??
  7. class??TcpClient??
  8. {??
  9. ????public?static?void?main(String[]?args)?throws?Exception??
  10. ????{??
  11. ????????//1、創建客戶端的Socket服務。指定目的主機和端口??
  12. ????????Socket?s=new?Socket("127.0.0.1",10000);??
  13. ????????//2、獲取Socket流中輸出流,發送數據??
  14. ????????OutputStream?out=s.getOutputStream();??
  15. ????????out.write("你好!".getBytes());??
  16. ????????//3、獲取Socket流中的輸入流,用來接收服務端的反饋信息并打印??
  17. ????????InputStream?in=s.getInputStream();??
  18. ??????????
  19. ????????byte[]?buf=new?byte[1024];??
  20. ????????int?len=in.read(buf);//讀取反饋的數據??
  21. ??
  22. ????????//輸出接收的數據??
  23. ????????System.out.println(new?String(buf,0,len));??
  24. ??
  25. ????????s.close();//關閉資源??
  26. ????}??
  27. }??
  28. ??
  29. ??
  30. //服務端??
  31. ??
  32. class?TcpServer??
  33. {??
  34. ????public?static?void?main(String[]?args)throws?Exception??
  35. ????{??
  36. ????????//1、創建服務端的Socket服務,并監聽一個端口??
  37. ????????ServerSocket?ss=new?ServerSocket(10000);??
  38. ????????//2、通過accept方法獲取連接過來的客戶端對象。??
  39. ????????Socket?s=ss.accept();??
  40. ????????//獲取客戶端ip??
  41. ????????String?ip=s.getInetAddress().getHostName();??
  42. ????????System.out.println(ip+"connected....");??
  43. ????????//3、獲取對應客戶端對象的讀取流讀取發過來的數據,并打印??
  44. ????????InputStream?in=s.getInputStream();??
  45. ????????byte[]?buf=new?byte[1024];??
  46. ????????int?len=in.read(buf);??
  47. ????????System.out.println(new?String(buf,0,len));??
  48. ??
  49. ????????//4、調用對應的客戶端的輸出流寫入返回數據??
  50. ????????OutputStream?out=s.getOutputStream();??
  51. ????????out.write("哥們,收到!".getBytes());??
  52. ??
  53. ????????//關閉資源??
  54. ????????s.close();??
  55. ????????ss.close();//可選操作??
  56. ????}??
  57. }??

練習一

[java]?view plaincopy
  1. /*?
  2. 練習?
  3. 需求:建立一個文本轉換服務器?
  4. 客戶端給服務端發送文本,服務端會將文本轉成大寫再返回給客戶端。?
  5. 而且客戶端可以不斷的進行文本轉換。當客戶端輸入over時,轉換結束。?
  6. ?
  7. 分析:?
  8. 客戶端:?
  9. 既然是操作設備上的數據,那么就可以使用io技術,并按照io的操作規律來思考。?
  10. 源:鍵盤錄入?
  11. 目的:網絡設備,網絡輸出流。?
  12. 而且操作的是文本數據。可以選擇字符流。?
  13. ?
  14. 步驟:?
  15. 1、建立服務?
  16. 2、獲取鍵盤錄入?
  17. 3、將數據發給服務端?
  18. 4、獲取服務端返回的大寫數據?
  19. 5、結束,管資源。?
  20. ?
  21. 都是文本數據,可以使用字符流進行操作,同時提高效率,加入緩沖。?
  22. ?
  23. ?
  24. 此練習出現的問題:?
  25. 現象:客戶端和服務端都在莫名的等待。?
  26. 原因:因為客戶端和服務端都有阻塞式方法。這些方法沒有讀到結束標記。那么就一直等。而導致兩端都在等待。?
  27. 解決:需要用到刷新和換行的方式將寫入和讀取的數據從流中刷新到內存中?
  28. ????方式一:可用高效緩沖區類的newLine()換行作為結束標記,并用flush()進行刷新。?
  29. 方式二:可用PrintWriter(s.getOutputStrean(),true)創建輸出流對象,true作用是刷新,通過打印方法println()換行,“ln”表示換行。?
  30. ?
  31. */??
  32. ??
  33. import?java.io.*;??
  34. import?java.net.*;??
  35. class??TcpClient??
  36. {??
  37. ????public?static?void?main(String[]?args)?throws?Exception??
  38. ????{??
  39. ????????//創建Socket服務??
  40. ????????Socket?s=new?Socket("127.0.0.1",10000);??
  41. ??????????
  42. ????????//定義讀取鍵盤數據的流對象??
  43. ????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??
  44. ??????????
  45. ????????//定義目的,將數據寫入到Socket輸出流。發給服務端??
  46. ????????//BufferedWriter?bwout=new?BufferedWriter(new?OutputStreamWriter(s.getOutputStream()));??
  47. ????????PrintWriter?pw=new?PrintWriter(s.getOutputStream(),true);??
  48. ??????????
  49. ????????//定義一個Socket讀取流,讀取服務端返回的大寫信息。??
  50. ????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  51. ??
  52. ????????String?line=null;??
  53. ????????while?((line=br.readLine())!=null)??
  54. ????????{??
  55. ??????????????
  56. ????????????if("over".equals(line))??
  57. ????????????????break;??
  58. ??
  59. ????????????//bwout.write(line);//寫入輸出流??
  60. ????????????//bwout.newLine();//換行??
  61. ????????????//bwout.flush();//刷新??
  62. ????????????pw.println(line);//將數據寫入流中??
  63. ??
  64. ????????????String?data=brin.readLine();//讀取返回的信息??
  65. ????????????System.out.println(data);??
  66. ??
  67. ????????}??
  68. ????????br.close();//關流??
  69. ????????s.close();??
  70. ????}??
  71. }??
  72. /*?
  73. 服務端:?
  74. 源:Socket讀取流?
  75. 目的:Socket輸出流?
  76. 都是文本,裝飾?
  77. */??
  78. ??
  79. class?TcpServer??
  80. {??
  81. ????public?static?void?main(String[]?args)throws?Exception??
  82. ????{??
  83. ????????//創建服務端的ServerSocket服務,并指定監聽端口??
  84. ????????ServerSocket?ss?=new?ServerSocket(10000);??
  85. ??????????
  86. ????????//獲取客戶端連接??
  87. ????????Socket?s=ss.accept();??
  88. ??
  89. ????????//獲取客戶端ip??
  90. ????????System.out.println(s.getInetAddress().getHostName()+"?connected.......");??
  91. ??
  92. ????????//讀取Socket讀取流中的數據??
  93. ????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  94. ??
  95. ????????//將大寫數據寫入到Socket輸出流,并發送給客戶端。??
  96. ????????//BufferedWriter?bwout=new?BufferedWriter(new?OutputStreamWriter(s.getOutputStream()));??
  97. ????????PrintWriter?pw=new?PrintWriter(s.getOutputStream(),true);??
  98. ??
  99. ????????String?line=null;??
  100. ????????while?((line=brin.readLine())!=null)??
  101. ????????{??
  102. ????????????System.out.println(line);??
  103. ??
  104. ????????????//bwout.write(line.toUpperCase());//將讀到數據轉換為大寫后返回??
  105. ????????????//bwout.newLine();//換行??
  106. ????????????//bwout.flush();//刷新??
  107. ??
  108. ????????????pw.println(line.toUpperCase());//將讀到數據轉換為大寫后返回??
  109. ????????}??
  110. ????????s.close();//關流??
  111. ????????ss.close();關閉資源(可選)??
  112. ????}??
  113. }??

練習二

[java]?view plaincopy
  1. /*?
  2. 需求:向服務器上傳一個文件,服務返回一條信息?
  3. 1、客戶端:?
  4. 源:硬盤上的文件;目的:網絡設備,即網絡輸出流。?
  5. 若操作的是文本數據,可選字符流,并加入高效緩沖區。若是媒體文件,用字節流。?
  6. ?
  7. 2、服務端:?
  8. 源:socket讀取流;目的:socket輸出流。?
  9. ?
  10. 3、出現的問題:??
  11. 現象:?
  12. a、文件已經上傳成功了,但是沒有得到服務端的反饋信息。?
  13. b、即使得到反饋信息,但得到的是null,而不是“上傳成功”的信息?
  14. ?
  15. 原因:?
  16. a、因為客戶端將數據發送完畢后,服務端仍然在等待這讀取數據,并沒有收到結束標記,就會一直等待讀取。?
  17. b、上個問題解決后,收到的不是指定信息而是null,是因為服務端寫入數據后,需要刷新,才能將信息反饋給客服端。?
  18. ?
  19. 解決:?
  20. 方法一:定義結束標記,先將結束標記發送給服務端,讓服務端接收到結束標記,然后再發送上傳的數據。但是這樣定義可能會發生定義的標記和文件中的數據重復,而導致提前結束。?
  21. ???方法二:定義時間戳,由于時間是唯一的,在發送數據前,先獲取時間,發送完后在結尾處寫上相同的時間戳,在服務端,接收數據前先接收一個時間戳,然后在循環中判斷時間戳以結束標記。?
  22. ??方法三:通過socket方法中的shutdownOutput(),關閉輸入流資源,從而結束傳輸流,以給定結束標記。通常用這個方法。?
  23. */??
  24. ??
  25. import?java.io.*;??
  26. import?java.net.*;??
  27. ??
  28. ??
  29. //客戶端??
  30. class??TcpClient??
  31. {??
  32. ????public?static?void?main(String[]?args)?throws?Exception??
  33. ????{??
  34. ????????//創建Socket服務??
  35. ????????Socket?s=new?Socket("127.0.0.1",10000);??
  36. ??????????
  37. ????????//定義讀取流讀取文件數據??
  38. ????????BufferedReader?br=new?BufferedReader(new?FileReader("TcpDemo.java"));??
  39. ??
  40. ????????//定義目的,將數據寫入到Socket輸出流。發給服務端??
  41. ????????//BufferedWriter?bwout=new?BufferedWriter(new?OutputStreamWriter(s.getOutputStream()));??
  42. ????????PrintWriter?pw=new?PrintWriter(s.getOutputStream(),true);??
  43. ??
  44. ????????//定義一個Socket讀取流,讀取服務端返回信息。??
  45. ????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  46. ??
  47. ????????String?line=null;??
  48. ????????while?((line=br.readLine())!=null)??
  49. ????????{??
  50. ????????????pw.println(line);??
  51. ????????}??
  52. ??????????
  53. ????????s.shutdownOutput();//關閉客戶端的輸出流。相當于給流中加入一個結束標記-1.??
  54. ??
  55. ????????System.out.println(brin.readLine());//接收返回信息??
  56. ??????????
  57. ????????br.close();??
  58. ????????s.close();??
  59. ????}??
  60. }??
  61. ??
  62. //服務端??
  63. class?TcpServer??
  64. {??
  65. ????public?static?void?main(String[]?args)throws?Exception??
  66. ????{??
  67. ????????//創建服務端的ServerSocket服務,并指定監聽端口??
  68. ????????ServerSocket?ss?=new?ServerSocket(10000);??
  69. ??????????
  70. ????????//獲取客戶端連接??
  71. ????????Socket?s=ss.accept();??
  72. ??
  73. ????????//獲取客戶端ip??
  74. ????????System.out.println(s.getInetAddress().getHostName()+"?connected.......");??
  75. ??
  76. ????????//讀取Socket讀取流中的數據??
  77. ????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  78. ??
  79. ????????//將接收到的數據寫入文件中??
  80. ????????PrintWriter?out=new?PrintWriter(new?FileWriter("TcpDemo.txt"),true);??
  81. ??????????
  82. ????????//將返回信息寫入Socket流的寫入流中??
  83. ????????BufferedWriter?bwout=new?BufferedWriter(new?OutputStreamWriter(s.getOutputStream()));??
  84. ??
  85. ????????String?line=null;??
  86. ????????while?((line=brin.readLine())!=null)??
  87. ????????{??
  88. ????????????out.println(line);??
  89. ????????}??
  90. ??
  91. ????????//PrintWriter?pw?=?new?PrintWriter(s.getOutputStream(),true);??
  92. ????????//pw.println("上傳成功");??
  93. ??????????
  94. ????????bwout.write("上傳成功!");??
  95. ????????bwout.newLine();//換行??
  96. ????????bwout.flush();//刷新??
  97. ??
  98. ????????out.close();//關流??
  99. ????????s.close();??
  100. ????????ss.close();??
  101. ????}??
  102. }??

?

第三講?????應用

一、用TCP客戶端并發上傳圖片

1、一對一(單線程)上傳的思路:

客戶端

??????? a、服務端點。

??????? b、讀取客戶端已有的圖片數據

??????? c、通過Socket輸出流將數據發給服務端

??????? d、讀取服務端反饋信息。

??????? e、關閉

服務端

?????? ?a、服務端服務,并監聽窗口

??????? b、獲取客戶端對象,并獲取客戶ip

??????? c、讀取客戶端輸入流數據

??????? d、寫入文件

??????? e、用客戶端輸出流反饋信息

??????? f、關流

2、單線程的服務端有個局限性。當A客戶端連接上以后,被服務端獲取到。服務端執行具體流程。這時B客戶端連接,只能等待。因為服務端還沒有處理完A客戶端的請求。還沒有循環回來執行下一次accept方法。所以,暫時獲取不到B客戶端對象。

??????? 那么為了可以讓多個客戶端同時并發訪問服務端。服務端最好就是將每個客戶端封裝到一個單獨的線程中,這樣,就可以同時處理多個客戶端請求。

如何定義線程呢?

??????? 只要明確了每一個客戶端要在服務端執行的代碼,將該代碼存入run方法即可。

代碼:

[java]?view plaincopy
  1. /*?
  2. 需求:并發上傳圖片?
  3. */??
  4. ??
  5. import?java.io.*;??
  6. import?java.net.*;??
  7. //客戶端??
  8. class??PicClient??
  9. {??
  10. ????public?static?void?main(String[]?args)?throws?Exception??
  11. ????{??
  12. ????????//對傳入的值進行判斷??
  13. ????????if?(args.length!=1)??
  14. ????????{??
  15. ????????????System.out.println("請指定一個圖片文件!");??
  16. ????????????return;??
  17. ????????}??
  18. ??
  19. ????????File?file=new?File(args[0]);??
  20. ??
  21. ????????//對文件路徑進行判斷??
  22. ????????if?(!(file.exists()&&file.isFile()))??
  23. ????????{??
  24. ????????????System.out.println("你上傳的文件有問題,非文件或者不存在!");??
  25. ????????????return;??
  26. ????????}??
  27. ??
  28. ????????//判斷是否是圖片文件??
  29. ????????if?(!file.getName().endsWith(".jpg"))??
  30. ????????{??
  31. ????????????System.out.println("圖片格式錯誤,請重新選擇!");??
  32. ????????????return;??
  33. ????????}??
  34. ??
  35. ????????//對文件大小進行判斷??
  36. ????????if?(file.length()>1024*1024*5)??
  37. ????????{??
  38. ????????????System.out.println("你上傳的文件過大,居心叵測!");??
  39. ????????????return;??
  40. ????????}??
  41. ??
  42. ????????//創建服務??
  43. ????????Socket?s=new?Socket("localhost",10000);??
  44. ????????//讀取圖片數據??
  45. ????????FileInputStream?fis=new?FileInputStream(file);??
  46. ??????????
  47. ????????//用Socket服務輸出流寫入數據??
  48. ????????OutputStream?out?=s.getOutputStream();??
  49. ??
  50. ????????BufferedReader?in=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  51. ??
  52. ????????byte[]?buf=new?byte[1024];??
  53. ??
  54. ????????int?len=0;??
  55. ??
  56. ????????while?((len=fis.read(buf))!=-1)??
  57. ????????{??
  58. ????????????out.write(buf,0,len);??
  59. ????????}??
  60. ??
  61. ????????//結束標記,表示文件數據已經上傳完了??
  62. ????????s.shutdownOutput();??
  63. ??
  64. ????????String?info=in.readLine();//讀取返回信息??
  65. ????????System.out.println(info);??
  66. ??
  67. ????????fis.close();//關流??
  68. ????????s.close();??
  69. ??
  70. ????}??
  71. }??
  72. ??
  73. //服務端??
  74. class?PicServer??
  75. {??
  76. ????public?static?void?main(String[]?args)throws?Exception??
  77. ????{??
  78. ????????//創建服務,監聽端口??
  79. ????????ServerSocket?ss=new?ServerSocket(10000);??
  80. ??????????
  81. ????????while?(true)??
  82. ????????{??
  83. ????????????//獲取客戶端對象??
  84. ????????????Socket?s=ss.accept();??
  85. ????????????//客戶端執行線程??
  86. ????????????new?Thread(new?PicThread(s)).start();??
  87. ????????}??
  88. ??????????
  89. ????????//ss.close();??
  90. ????}??
  91. }??
  92. ??
  93. //利用多線程實現并發上傳??
  94. class?PicThread?implements?Runnable??
  95. {??
  96. ????private?Socket?s;??
  97. ????PicThread(Socket?s)??
  98. ????{??
  99. ????????this.s=s;??
  100. ????}??
  101. ????public?void?run()??
  102. ????{??
  103. ????????int?count=1;??
  104. ????????//獲取客戶端ip??
  105. ????????String?ip=s.getInetAddress().getHostAddress();??
  106. ????????try??
  107. ????????{?????????
  108. ????????????System.out.println(ip+"??connected.....");??
  109. ??
  110. ????????????//通過客戶端的讀取流讀取數據??
  111. ????????????InputStream?in=s.getInputStream();??
  112. ????????????//文件保存路徑??
  113. ????????????File?dir?=new?File("C:\\Users\\asus\\Desktop");??
  114. ????????????//文件名??
  115. ????????????File?file=new?File(dir,ip+".jpg");??
  116. ????????????//判斷文件是否存在??
  117. ????????????while(file.exists())??
  118. ????????????{??
  119. ????????????????file=new?File(dir,ip+"("+(count++)+").jpg");??
  120. ????????????}??
  121. ??
  122. ????????????//將數據寫入到指定文件中??
  123. ????????????FileOutputStream?fos=new?FileOutputStream(file);??
  124. ??
  125. ????????????byte[]?buf=new?byte[1024];??
  126. ????????????int?len=0;??
  127. ????????????while?((len=in.read(buf))!=-1)??
  128. ????????????{??
  129. ????????????????fos.write(buf,0,len);??
  130. ????????????}??
  131. ??
  132. ????????????//將收到圖片數據的信息返回給客戶端??
  133. ????????????OutputStream?out=s.getOutputStream();??
  134. ??????????????
  135. ????????????out.write("上傳成功!".getBytes());??
  136. ??
  137. ????????????fos.close();//關流??
  138. ????????????s.close();??
  139. ????????}??
  140. ????????catch?(Exception?e)??
  141. ????????{??
  142. ????????????throw?new?RuntimeException(ip+"圖片上傳失敗");??
  143. ????????}??
  144. ????}??
  145. }??


二、客戶端并發登錄

????????客戶端通過鍵盤錄入用戶名,服務端對這個用戶名進行校驗。

??????? 如果該用戶存在,在服務端顯示xxx,已登陸;并在客戶端顯示xxx,歡迎光臨。

??????? 如果用戶不存在,在服務端顯示xxx,嘗試登陸;并在客戶端顯示xxx,該用戶不存在。

??????? 最多就登錄三次。

代碼:?

[java]?view plaincopy
  1. import?java.io.*;??
  2. import?java.net.*;??
  3. //客戶端??
  4. class??LoginClient??
  5. {??
  6. ????public?static?void?main(String[]?args)?throws?Exception??
  7. ????{??
  8. ????????//創建服務??
  9. ????????Socket?s=new?Socket("localhost",10000);??
  10. ????????//鍵盤錄入??
  11. ????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??
  12. ??
  13. ??????????
  14. ????????//用Socket服務輸出流寫入數據??
  15. ????????PrintWriter?out?=new?PrintWriter(s.getOutputStream(),true?);??
  16. ??
  17. ????????//接收服務器返回的信息??
  18. ????????BufferedReader?in=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  19. ??
  20. ????????String?line=null;??
  21. ??
  22. ????????for(int?x=0;x<3;x++)??
  23. ????????{??
  24. ????????????line=br.readLine();//讀取鍵盤錄入??
  25. ????????????if?(line==null)??
  26. ????????????{??
  27. ????????????????break;//如果鍵盤沒有輸入,則直接結束??
  28. ????????????}??
  29. ??
  30. ????????????out.println(line);//將數據寫入流中??
  31. ??
  32. ????????????String?info=in.readLine();//讀取返回信息??
  33. ??
  34. ????????????System.out.println(info);??
  35. ??
  36. ????????????if?(info.contains("歡迎"))//---------------??
  37. ????????????{??
  38. ????????????????break;//如果登錄成功,就跳出循環??
  39. ????????????}??
  40. ????????}??
  41. ??
  42. ????????br.close();//關流??
  43. ????????s.close();??
  44. ????}??
  45. }??
  46. ??
  47. //服務端??
  48. class?LoginServer??
  49. {??
  50. ????public?static?void?main(String?[]?args)throws?Exception??
  51. ????{??
  52. ????????//創建服務,監聽端口??
  53. ????????ServerSocket?ss=new?ServerSocket(10000);??
  54. ??????????
  55. ????????while?(true)??
  56. ????????{??
  57. ????????????//獲取客戶端對象??
  58. ????????????Socket?s=ss.accept();??
  59. ??????????
  60. ????????????//客戶端執行線程??
  61. ????????????new?Thread(new?LoginThread(s)).start();??
  62. ????????}??
  63. ??????????
  64. ????????//ss.close();??
  65. ????}??
  66. }??
  67. ??
  68. //利用多線程實現并發登錄??
  69. class?LoginThread?implements?Runnable??
  70. {??
  71. ????private?Socket?s;??
  72. ????LoginThread(Socket?s)??
  73. ????{??
  74. ????????this.s=s;??
  75. ????}??
  76. ????public?void?run()??
  77. ????{??
  78. ????????//獲取客戶端ip??
  79. ????????String?ip=s.getInetAddress().getHostAddress();??
  80. ????????System.out.println(ip+"??connected.....");??
  81. ????????try??
  82. ????????{?????????
  83. ????????????for?(int?x=0;x<3?;x++?)??
  84. ????????????{?????
  85. ????????????????//通過客戶端的讀取流讀取數據??
  86. ????????????????BufferedReader?in=new?BufferedReader(new?InputStreamReader(s.getInputStream()));??
  87. ??????????????????
  88. ????????????????//讀取數據庫中的數據,這里用文件來表示數據庫??
  89. ????????????????BufferedReader?br=new?BufferedReader(new?FileReader("users.txt"));??
  90. ??
  91. ????????????????String?line=in.readLine();//讀取客戶端數據??
  92. ????????????????if?(line==null)//--------------??
  93. ????????????????{??
  94. ????????????????????break;//如果客戶端沒有發送數據,則跳出循環??
  95. ????????????????}??
  96. ????????????????String?data=null;??
  97. ????????????????boolean?flag=false;//設置標記??
  98. ????????????????//讀取數據庫中的用戶數據??
  99. ????????????????while?((data=br.readLine())!=null)??
  100. ????????????????{??
  101. ????????????????????if?(line.equals(data))??
  102. ????????????????????{??
  103. ????????????????????????flag=true;//如果用戶存在,則將標記設為true??
  104. ????????????????????????break;??
  105. ????????????????????}??
  106. ????????????????}??
  107. ??
  108. ????????????????//將數據寫入到指定文件中??
  109. ????????????????PrintWriter?out=new?PrintWriter(s.getOutputStream(),true);??
  110. ??
  111. ????????????????if?(flag)??
  112. ????????????????{??
  113. ????????????????????System.out.println(line+",已登陸!");??
  114. ??????????????????????
  115. ????????????????????out.println(line+",歡迎光臨!");??
  116. ??
  117. ????????????????????break;//-----------??
  118. ????????????????}??
  119. ????????????????else??
  120. ????????????????{??
  121. ????????????????????System.out.println(line+",嘗試登陸!");??
  122. ????????????????????out.println(line+",用戶名不存在!");??
  123. ????????????????}?????
  124. ????????????}??
  125. ????????????s.close();//關流??
  126. ????????}??
  127. ????????catch?(Exception?e)??
  128. ????????{??
  129. ????????????throw?new?RuntimeException("用戶登陸失敗");??
  130. ????????}?????
  131. ????}??
  132. }??


三、客戶端和服務的瀏覽器演示

??????? 瀏覽器是一個標準的客戶端,它可以對服務端傳送過來的數據消息進行解析,把符合應用層協議的消息部分解析后,將頭信息拆包掉,傳送到應用層,只保留了正確的正文主題部分顯示在主體部分上。

??????? 而由于使用java編譯是在傳輸層和網際層處理的,所以,會接受到全部的消息,包含了頭消息。而瀏覽器處于應用層,已將發送來的頭消息去除,只留下了主體信息。

示例:

??????? 自定義服務器,用瀏覽器訪問:

[java]?view plaincopy
  1. import?java.io.*;??
  2. import?java.net.*;??
  3. ??
  4. //服務器??
  5. class??ServerDemo??
  6. {??
  7. ????public?static?void?main(String[]?args)throws?Exception???
  8. ????{??
  9. ????????//創建服務,監聽端口??
  10. ????????ServerSocket?ss=new?ServerSocket(10000);??
  11. ????????//獲取客戶端??
  12. ????????Socket?s=ss.accept();??
  13. ????????//顯示ip??
  14. ????????String?ip=s.getInetAddress().getHostAddress();??
  15. ??
  16. ????????System.out.println(ip);??
  17. ????????//讀取客戶端讀取流數據??
  18. ????????InputStream?in=s.getInputStream();??
  19. ??
  20. ????????byte[]?buf=new?byte[1024];??
  21. ????????int?len=in.read(buf);??
  22. ????????//顯示數據??
  23. ????????System.out.println(new?String(buf,0,len));??
  24. ????????//返回信息寫入客戶端輸出流??
  25. ????????PrintWriter?out=new?PrintWriter(s.getOutputStream(),true);///true一定要記得寫??
  26. ??
  27. ????????out.println("<font?color='red'?size='7'>客戶端你好!</font>");??
  28. ??
  29. ????????s.close();//關流??
  30. ????????ss.close();??
  31. ????}??
  32. }??

?

四、URL和URLConnection

1、URL:

??????? URI:范圍更大,條形碼也包含于此范圍

??????? URL:范圍較小,即域名

方法:

??????? 1)構造函數:URL(String protocol,String host,int port,String file);//根據指定?protocol、host、port號和?file?創建?URL對象。

??????? 2)String getProtocol();//獲取協議名稱

??????? 3)String getHost();//獲取主機名

??????? 4)int getPort();//獲取端口號

??????? 5)String getFile();//獲取URL文件名

??????? 6)String getPath();//獲取此URL的路徑部分

??????? 7)String getQuery();//獲取此URL的查詢部,客戶端傳輸的特定信息

注:一般輸入網址,是不帶端口號的,此時可進行獲取,通過獲取網址返回的port,若port為-1,則分配一個默認的80端口,如

??????? int port = getPort();

??????? if(port == -1)

????????????? port = 80;

2、URLConnection

方法:

??????? 1)URLConnection openConnection();//用URL調用此方法,返回一個?URLConnection?對象,它表示到?URL?所引用的遠程對象的連接。

??????? 2)InputStream getInputStream();//獲取輸入流

??????? 3)OutputStream getOutputStream();//獲取輸出流

示例:

[java]?view plaincopy
  1. /*?
  2. 自定義瀏覽器,顯示網頁信息?
  3. */??
  4. ??
  5. import?java.io.*;??
  6. import?java.awt.*;??
  7. import?java.awt.event.*;??
  8. import?java.net.*;??
  9. ??
  10. class?MyIEGUIDemo??
  11. {??
  12. ????//定義所需組件引用??
  13. ????private?Frame?f;??
  14. ????private?Button?but,bok;??
  15. ????private?TextField?tf;??
  16. ????private?TextArea?ta;??
  17. ??
  18. ????//構造函數??
  19. ????MyIEGUIDemo()??
  20. ????{??
  21. ????????init();??
  22. ????}??
  23. ??
  24. ????//窗體基本設置于功能實現??
  25. ????public?void?init()??
  26. ????{??
  27. ????????//組件實例化??
  28. ????????f=new?Frame("我的Window");??
  29. ????????but=new?Button("跳轉");??
  30. ????????tf=new?TextField(50);??
  31. ????????ta=new?TextArea(25,60);??
  32. ??
  33. ????????//基本設置??
  34. ????????f.setBounds(300,150,500,500);??
  35. ????????f.setLayout(new?FlowLayout());??
  36. ??
  37. ????????//添加組件??
  38. ????????f.add(tf);??
  39. ????????f.add(but);??
  40. ????????f.add(ta);??
  41. ??
  42. ????????//窗體事件??
  43. ????????myEvent();??
  44. ??
  45. ????????//窗體顯示??
  46. ????????f.setVisible(true);??
  47. ????}??
  48. ??
  49. ????//注冊事件??
  50. ????public?void?myEvent()??
  51. ????{??
  52. ????????//窗體關閉功能??
  53. ????????f.addWindowListener(new?WindowAdapter()??
  54. ????????{??
  55. ????????????public?void?windowClosing(WindowEvent?e)??
  56. ????????????{??
  57. ????????????????System.exit(0);??
  58. ????????????}??
  59. ????????});??
  60. ??
  61. ????????//“跳轉”按鈕事件??
  62. ????????but.addActionListener(new?ActionListener()??
  63. ????????{??
  64. ????????????public?void?actionPerformed(ActionEvent?e)??
  65. ????????????{??
  66. ????????????????showFile();//顯示網頁內容在文本區中??
  67. ????????????}??
  68. ????????});??
  69. ??
  70. ??????????
  71. ??
  72. ????????//文本框鍵盤事件??
  73. ????????tf.addKeyListener(new?KeyAdapter()??
  74. ????????{??
  75. ????????????public?void?keyPressed(KeyEvent?e)??
  76. ????????????{??
  77. ????????????????//如果鍵盤按下Enter鍵,就將網頁內容顯示在文本區中??
  78. ????????????????if(e.getKeyCode()==KeyEvent.VK_ENTER)??
  79. ????????????????????showFile();??
  80. ????????????}??
  81. ????????});??
  82. ????}??
  83. ??
  84. ????//顯示網頁內容??
  85. ????????private?void?showFile()??
  86. ????????{??
  87. ????????????ta.setText("");??
  88. ????????????String?path=tf.getText();//獲取輸入的路徑??
  89. ????????????try??
  90. ????????????{??
  91. ????????????????//封裝地址對象??
  92. URL?url?=new?URL(path);??
  93. 連接網頁服務器??
  94. ????????????????URLConnection?conn=url.openConnection();??
  95. ????????????????//讀取流,用于讀取服務器返回數據??
  96. ????????????????InputStream?in=conn.getInputStream();??
  97. ??
  98. ????????????????byte[]?buf=new?byte[1024*1024];??
  99. ??
  100. ????????????????int?len=in.read(buf);??
  101. ????????????????//將數據顯示在文本區中??
  102. ????????????????ta.append(new?String(buf,0,len));??
  103. ????????????}??
  104. ????????????catch?(Exception?e)??
  105. ????????????{??
  106. ????????????????throw?new?RuntimeException("連接"+path+"網站失敗");??
  107. ????????????}??
  108. ????????}??
  109. ??
  110. ????public?static?void?main(String[]?args)???
  111. ????{??
  112. ????????//運行窗體??
  113. ????????new?MyIEGUIDemo();??
  114. ????}??
  115. }??

?

小知識點

1、Socket類的構造函數中,有一個空參數的構造函數:

??????? Socket()//通過系統默認類型的?SocketImpl創建未連接套接字對象

???????可以通過connect(SocketAddress endpoint)方法來連接服務器。而SocketAddress是一個抽象類,它的子類InetSocketAddress實現了IP套接字地址(IP地址+端口號)。所以就可以連接到服務器了。

2、ServerSocket對象中的構造函數:

??????? ServerSocket(int port,int backlog),其中的backlog表示隊列的最大長度,即最多連入客戶端的個數,即最大連接數。

3、在瀏覽器輸入網址訪問一臺主機所做的操作:

???????如輸入http://61.135.169.125,可以直接連接此ip的主機,而我們一般是輸入主機名:http:/www.baidu.ocm(百度主機對應的ip地址就是:61.135.169.125),那么此時瀏覽器做了神馬操作呢?

?????? 也就是說如何通過主機名獲取IP地址,從而連接到這臺主機呢?這就需要將主機名翻譯成IP地址,即域名解析:DNS

????????在進行訪問的時候,會先在本地的hosts文件(c:\windows\system32\drivers\ext\host)中找對應的映射。若有,則直接返回請求;若無,則到公網的映射列表即DNS中找對應的映射,找到后,將主機名對應的IP地址返回給本機,本機通過這個IP地址找到對應的服務器。

示意圖:

?host應用:可屏蔽一些惡意網址,即將對應的映射關系寫入hosts中,將IP地址改為本機的回環地址,那么會直接找到hosts,就不會將請求發送出去了。

?

轉載于:https://www.cnblogs.com/tiankong101/p/4227355.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273446.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273446.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273446.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AND、OR運算符的組合使用

6.2.3 AND、OR運算符的組合使用 在WHERE子句中&#xff0c;通過AND、OR運算符可以同時連接多個條件&#xff0c;當然AND、OR運算符也可以同時使用。但是當AND、OR運算符同時存在時&#xff0c;其優先級如何確定呢&#xff1f;與大多數語言一樣&#xff0c;SQL語言認為AND運算…

Nginx配置指定媒體類型文件強制下載

由于業務需要&#xff0c;在點擊顯示鏈接&#xff08;如www.xxx.com/2015-01-15/xxx.png&#xff09;顯示媒體資源&#xff08;如圖片、視頻、音頻、文檔&#xff09;&#xff0c;而在點擊下載鏈接&#xff08;如www.xxx.com/2015-01-15/xxx.png?downloadtrue&#xff09;請求…

IN運算符的使用

6.3 IN運算符 在查詢中&#xff0c;有時只要滿足多個條件中的一個條件即可&#xff0c;如查詢地址在北京、上海或者重慶的學生信息&#xff0c;這時候可以使用IN運算符。 6.3.1 IN運算符的使用 IN運算符允許根據一行記錄中&#xff0c;是否有一列包括在一系列值之中&#…

app后端設計(php)

來源&#xff1a;http://blog.csdn.net/column/details/mobilebackend.html?page1 做了3年app相關的系統架構&#xff0c;api設計&#xff0c;先后在3個創業公司中工作&#xff0c;經歷過手機網頁端&#xff0c;android客戶端&#xff0c;iphone客戶端&#xff0c;現在從事日p…

NOT運算符與運算符

6.4.2 NOT運算符與<>運算符 對于簡單的條件查詢&#xff0c;NOT運算符與<>運算符的功能幾乎沒有什么區別&#xff0c;那么NOT運算符的優勢體現在哪里呢&#xff1f;答案是它可以與其他運算符組合使用&#xff0c;這一點是<>運算符所不能實現的。在6.4.1節已…

bootstrap-wysiwyg 結合 base64 解碼 .net bbs 圖片操作類 (三) 圖片裁剪

官方的例子 是 長方形的。 我這里 用于 正方形的頭像 所以 做如下 修改 #preview-pane .preview-container {width: 73px;height: 73px;overflow: hidden;} 可惜很莫名奇妙的是 有的時候 他自動把圖片 變小了&#xff0c;而且針對的都是 小圖&#xff0c;大圖 都顯示正常 發現…

“%”通配符

6.5.2 “%”通配符 在SQL語言中最常用的通配符可能就是“%”了&#xff0c;它表示任意字符的匹配&#xff0c;且不計字符的多少。下面通過幾個典型實例來說明“%”通配符的使用。 1&#xff0e;開頭&#xff0f;結尾匹配 從COURSE表中查詢所有以“計算機”開頭的所有課程的…

Wireshark基本介紹和學習TCP三次握手

Wireshark基本介紹和學習TCP三次握手 原文&#xff1a;http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html wireshark介紹 wireshark的官方下載網站&#xff1a; http://www.wireshark.org/ wireshark是非常流行的網絡封包分析軟件&#xff0c;功能十分強大。可…

“_”通配符

6.5.3 “_”通配符 “_”通配符的功能與“%”通配符基本相同&#xff0c;只是它只表示任意一個字符的匹配。當然&#xff0c;要表示兩個字符的匹配&#xff0c;就需要使用兩個“_”通配符&#xff0c;即寫成“__”。 只有在用戶確定所要查詢的字符串的個數&#xff0c;只是不…

“[]”通配符

6.5.4 “[]”通配符 “[]”通配符用于指定一系列的字符&#xff0c;只要滿足這些字符其中之一&#xff0c;且位置出現在“[]”通配符的位置的字符串就滿足查詢條件。 當然&#xff0c;各種通配符也可以組合使用。組合使用各種通配符時&#xff0c;一定要弄清其表示的匹配條…

QT分頁控件,開源,供大家使用

下載地址&#xff1a;http://files.cnblogs.com/dragonsuc/qt5.rar 轉載于:https://www.cnblogs.com/dragonsuc/p/4242342.html

使用ESCAPE定義轉義符

6.5.5 使用ESCAPE定義轉義符 在使用LIKE關鍵字進行模糊查詢時&#xff0c;“%”、“_”和“[]”單獨出現時&#xff0c;會被認為是通配符。為了在字符數據類型的列中查詢是否存在百分號&#xff08;%&#xff09;、下劃線&#xff08;_&#xff09;或者方括號&#xff08;[]&…

STL學習小結

STL就是Standard Template Library&#xff0c;標準模板庫。這可能是一個歷史上最令人興奮的工具的最無聊的術語。從根本上說&#xff0c;STL是一些“容器”的集合&#xff0c;這些“容器”有list, vector,set,map等&#xff0c;STL也是算法和其它一些組件的集合。這里的“容器…

內連接(INNER JOIN)

9.3.3 內連接&#xff08;INNER JOIN&#xff09; 內連接也稱為等同連接&#xff0c;返回的結果集是兩個表中所有相匹配的數據&#xff0c;而舍棄不匹配的數據。也就是說&#xff0c;在這種查詢中&#xff0c;DBMS只返回來自源表中的相關的行&#xff0c;即查詢的結果表包含的…

幾個 PHP 的“魔術常量”

PHP 向它運行的任何腳本提供了大量的預定義常量。不過很多常量都是由不同的擴展庫定義的&#xff0c;只有在加載了這些擴展庫時才會出現&#xff0c;或者動態加載后&#xff0c;或者在編譯時已經包括進去了。 有八個魔術常量它們的值隨著它們在代碼中的位置改變而改變。例如 __…

外連接(OUTER JOIN)

9.3.4 外連接&#xff08;OUTER JOIN&#xff09; 不管是內連接還是帶WHERE子句的多表查詢&#xff0c;都組合自多個表&#xff0c;并生成結果表。換句話說&#xff0c;如果任何一個源表中的行在另一個源表中沒有匹配&#xff0c;DBMS將不把該行放在最后的結果表中。 而外連…

Android應用切換皮膚功能實現

原文地址&#xff1a;http://www.eoeandroid.com/thread-318159-1-1.html 現在大多數android應用都支持切換皮膚的功能。比如千千靜聽&#xff0c;墨跡天氣等等。本文介紹兩種切換皮膚的方法。1.第一種是通過安裝皮膚apk的方式。當安裝了皮膚apk包之后&#xff0c;主程序只需要…

交叉連接(CROSS JOIN)

9.3.5 交叉連接&#xff08;CROSS JOIN&#xff09; 除了在FROM子句中使用逗號間隔連接的表外&#xff0c;SQL還支持另一種被稱為交叉連接的操作&#xff0c;它們都返回被連接的兩個表所有數據行的笛卡爾積&#xff0c;返回到的數據行數等于第一個表中符合查詢條件的數據行數…

[BZOJ 1046] [HAOI2007] 上升序列 【DP】

題目鏈接&#xff1a;BZOJ - 1046 題目分析 先倒著做最長下降子序列&#xff0c;求出 f[i]&#xff0c;即以 i 為起點向后的最長上升子序列長度。 注意題目要求的是 xi 的字典序最小&#xff0c;不是數值&#xff01; 如果輸入的 l 大于最長上升子序列長度&#xff0c;輸出 Imp…

UNION運算符

9.4.2 UNION運算符 在SQL中&#xff0c;UNION運算符用于執行集合并的運算。關于UNION運算符的使用&#xff0c;這里通過實例來說明。 實例16 使用UNION運算符執行集合并的運算 在STUDENT表中&#xff0c;查詢選修了1號或者10號課程的學生的學號、姓名、所在系信息。實例代…