第一講??? ?概述?
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
import?java.net.*;??class?IPDemo???{??????public?static?void?main(String[]?args)throws?Exception???????{??????????????????InetAddress?ia=InetAddress.getLocalHost();????????????????????????????String?address=ia.getHostAddress();??????????????????String?name=ia.getHostName();??????????System.out.println("IP="+address+"\tname="+name);????????????????????InetAddress?i=InetAddress.getByName("192.168.1.175");????????????String?add=i.getHostAddress();??????????String?na=i.getHostName();??????????System.out.println("addIP="+add+"\tiname="+na);????????????????????InetAddress[]?baidu=InetAddress.getAllByName("www.baidu.com");??????????for?(InetAddress?b?:baidu)??????????{??????????????String?baddress=b.getHostAddress();??????????????String?bname=b.getHostName();??????????????System.out.println("baiduIP="+baddress+"\tbaiduname="+bname);??????????}??????}??}?? 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
??import?java.net.*;??class?UdpSend???{??????public?static?void?main(String[]?args)throws?Exception???????{??????????????????DatagramSocket?ds=new?DatagramSocket();??????????????????byte[]?buf="udp?shi?shen?ma".getBytes();??????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.175"),10000);????????????????????ds.send(dp);??????????????????ds.close();??????}??}??????class?UdpReceive??{??????public?static?void?main(String[]?args)throws?Exception??????{????????????????????????????????????????????while(true)??????????{??????????????????????????DatagramSocket?ds=new?DatagramSocket(10000);??????????????????????????byte[]?buf=new?byte[1024];??????????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length);??????????????????????????ds.receive(dp);????????????????????????String?ip=dp.getAddress().getHostName();??????????????String?data=new?String(dp.getData(),0,dp.getLength());??????????????int?port=dp.getPort();??????????????System.out.println(ip+"::"+data+"::"+port);??????????????????????????ds.close();??????????}??????????????????????}??}?? 練習一
[java]?view plaincopy
??import?java.net.*;??import?java.io.*;??class?UdpSend????{??????public?static?void?main(String[]?args)throws?Exception??????{??????????????????DatagramSocket?ds=new?DatagramSocket(9999);??????????????????DatagramPacket?dp=null;??????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??????????String?line=null;??????????while((line=br.readLine())!=null)??????????{??????????????byte[]?buf=line.getBytes();??????????????dp=new?DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10000);??????????????????????????ds.send(dp);??????????????if?("886".equals(line))??????????????{??????????????????break;??????????????}??????????}??????????????????ds.close();????????????????}??}????class?UdpReceive??{??????public?static?void?main(String[]?args)throws?Exception??????{??????????????????DatagramSocket?ds=new?DatagramSocket(10000);??????????????????while?(true)??????????{??????????????????????????byte[]?buf=new?byte[1024];??????????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length);??????????????????????????ds.receive(dp);??????????????????????????String?ip=dp.getAddress().getHostAddress();??????????????String?data=new?String(dp.getData(),0,dp.getLength());??????????????int?port=dp.getPort();????????????????System.out.println("IP:"+ip+"=="+data);??????????}??????????????????????}??}????? 練習二
[java]?view plaincopy
??import?java.net.*;??import?java.io.*;????class?UdpSend?implements?Runnable??{??????????private?DatagramSocket?ds;??????UdpSend(DatagramSocket?ds)??????{??????????this.ds=ds;??????}??????????public?void?run()??????{??????????try??????????{??????????????????????????DatagramPacket?dp=null;??????????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??????????????String?line=null;??????????????while((line=br.readLine())!=null)??????????????{??????????????????byte[]?buf=line.getBytes();??????????????????dp=new?DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10000);??????????????????????????????????ds.send(dp);??????????????????if?("886".equals(line))??????????????????{??????????????????????break;??????????????????}??????????????}??????????????????????????ds.close();??????????}??????????catch?(Exception?e)??????????{??????????????throw?new?RuntimeException("發送數據失敗");??????????}?????????????}??}????class?UdpReceive?implements?Runnable??{??????????private?DatagramSocket?ds;??????UdpReceive(DatagramSocket?ds)??????{??????????this.ds=ds;??????}??????????public?void?run()??????{??????????try??????????{??????????????????????????while?(true)??????????????{??????????????????????????????????byte[]?buf=new?byte[1024];??????????????????DatagramPacket?dp=new?DatagramPacket(buf,buf.length);??????????????????????????????????ds.receive(dp);??????????????????????????????????String?ip=dp.getAddress().getHostAddress();??????????????????String?data=new?String(dp.getData(),0,dp.getLength());??????????????????int?port=dp.getPort();????????????????????System.out.println("IP:"+ip+"=="+data);??????????????}??????????????????????????????????}??????????catch?(Exception?e)??????????{??????????????throw?new?RuntimeException("接收端接收數據失敗");??????????}??????}??}????class?UdpChatDemo??{??????public?static?void?main(String[]?args)throws?Exception??????{??????????new?Thread(new?UdpSend(new?DatagramSocket())).start();??????????new?Thread(new?UdpReceive(new?DatagramSocket(10000))).start();??????}??}?? 三、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
import?java.net.*;??import?java.io.*;??class??TcpClient??{??????public?static?void?main(String[]?args)?throws?Exception??????{??????????????????Socket?s=new?Socket("127.0.0.1",10000);??????????????????OutputStream?out=s.getOutputStream();??????????out.write("你好!".getBytes());??????????????????InputStream?in=s.getInputStream();????????????????????byte[]?buf=new?byte[1024];??????????int?len=in.read(buf);??????????????????System.out.println(new?String(buf,0,len));????????????s.close();????}??}????????class?TcpServer??{??????public?static?void?main(String[]?args)throws?Exception??????{??????????????????ServerSocket?ss=new?ServerSocket(10000);??????????????????Socket?s=ss.accept();??????????????????String?ip=s.getInetAddress().getHostName();??????????System.out.println(ip+"connected....");??????????????????InputStream?in=s.getInputStream();??????????byte[]?buf=new?byte[1024];??????????int?len=in.read(buf);??????????System.out.println(new?String(buf,0,len));????????????????????OutputStream?out=s.getOutputStream();??????????out.write("哥們,收到!".getBytes());????????????????????s.close();??????????ss.close();????}??}?? 練習一
[java]?view plaincopy
??import?java.io.*;??import?java.net.*;??class??TcpClient??{??????public?static?void?main(String[]?args)?throws?Exception??????{??????????????????Socket?s=new?Socket("127.0.0.1",10000);????????????????????????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));????????????????????????????????????PrintWriter?pw=new?PrintWriter(s.getOutputStream(),true);????????????????????????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????String?line=null;??????????while?((line=br.readLine())!=null)??????????{????????????????????????????if("over".equals(line))??????????????????break;????????????????????????????????????????????????????pw.println(line);??????????????String?data=brin.readLine();????????????System.out.println(data);????????????}??????????br.close();????????s.close();??????}??}????class?TcpServer??{??????public?static?void?main(String[]?args)throws?Exception??????{??????????????????ServerSocket?ss?=new?ServerSocket(10000);????????????????????????????Socket?s=ss.accept();????????????????????System.out.println(s.getInetAddress().getHostName()+"?connected.......");????????????????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????????????????????PrintWriter?pw=new?PrintWriter(s.getOutputStream(),true);????????????String?line=null;??????????while?((line=brin.readLine())!=null)??????????{??????????????System.out.println(line);??????????????????????????????????????????????????????pw.println(line.toUpperCase());????????}??????????s.close();????????ss.close();關閉資源(可選)??????}??}?? 練習二
[java]?view plaincopy
??import?java.io.*;??import?java.net.*;??????class??TcpClient??{??????public?static?void?main(String[]?args)?throws?Exception??????{??????????????????Socket?s=new?Socket("127.0.0.1",10000);????????????????????????????BufferedReader?br=new?BufferedReader(new?FileReader("TcpDemo.java"));????????????????????????????PrintWriter?pw=new?PrintWriter(s.getOutputStream(),true);????????????????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????String?line=null;??????????while?((line=br.readLine())!=null)??????????{??????????????pw.println(line);??????????}????????????????????s.shutdownOutput();??????????System.out.println(brin.readLine());??????????????????br.close();??????????s.close();??????}??}????class?TcpServer??{??????public?static?void?main(String[]?args)throws?Exception??????{??????????????????ServerSocket?ss?=new?ServerSocket(10000);????????????????????????????Socket?s=ss.accept();????????????????????System.out.println(s.getInetAddress().getHostName()+"?connected.......");????????????????????BufferedReader?brin=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????????????PrintWriter?out=new?PrintWriter(new?FileWriter("TcpDemo.txt"),true);????????????????????????????BufferedWriter?bwout=new?BufferedWriter(new?OutputStreamWriter(s.getOutputStream()));????????????String?line=null;??????????while?((line=brin.readLine())!=null)??????????{??????????????out.println(line);??????????}??????????????????????????????????????bwout.write("上傳成功!");??????????bwout.newLine();????????bwout.flush();??????????out.close();????????s.close();??????????ss.close();??????}??}?? ?
第三講?????應用
一、用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
??import?java.io.*;??import?java.net.*;??class??PicClient??{??????public?static?void?main(String[]?args)?throws?Exception??????{??????????????????if?(args.length!=1)??????????{??????????????System.out.println("請指定一個圖片文件!");??????????????return;??????????}????????????File?file=new?File(args[0]);????????????????????if?(!(file.exists()&&file.isFile()))??????????{??????????????System.out.println("你上傳的文件有問題,非文件或者不存在!");??????????????return;??????????}????????????????????if?(!file.getName().endsWith(".jpg"))??????????{??????????????System.out.println("圖片格式錯誤,請重新選擇!");??????????????return;??????????}????????????????????if?(file.length()>1024*1024*5)??????????{??????????????System.out.println("你上傳的文件過大,居心叵測!");??????????????return;??????????}????????????????????Socket?s=new?Socket("localhost",10000);??????????????????FileInputStream?fis=new?FileInputStream(file);????????????????????????????OutputStream?out?=s.getOutputStream();????????????BufferedReader?in=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????byte[]?buf=new?byte[1024];????????????int?len=0;????????????while?((len=fis.read(buf))!=-1)??????????{??????????????out.write(buf,0,len);??????????}????????????????????s.shutdownOutput();????????????String?info=in.readLine();????????System.out.println(info);????????????fis.close();????????s.close();????????}??}????class?PicServer??{??????public?static?void?main(String[]?args)throws?Exception??????{??????????????????ServerSocket?ss=new?ServerSocket(10000);????????????????????while?(true)??????????{??????????????????????????Socket?s=ss.accept();??????????????????????????new?Thread(new?PicThread(s)).start();??????????}????????????????????????}??}????class?PicThread?implements?Runnable??{??????private?Socket?s;??????PicThread(Socket?s)??????{??????????this.s=s;??????}??????public?void?run()??????{??????????int?count=1;??????????????????String?ip=s.getInetAddress().getHostAddress();??????????try??????????{?????????????????????System.out.println(ip+"??connected.....");????????????????????????????InputStream?in=s.getInputStream();??????????????????????????File?dir?=new?File("C:\\Users\\asus\\Desktop");??????????????????????????File?file=new?File(dir,ip+".jpg");??????????????????????????while(file.exists())??????????????{??????????????????file=new?File(dir,ip+"("+(count++)+").jpg");??????????????}????????????????????????????FileOutputStream?fos=new?FileOutputStream(file);????????????????byte[]?buf=new?byte[1024];??????????????int?len=0;??????????????while?((len=in.read(buf))!=-1)??????????????{??????????????????fos.write(buf,0,len);??????????????}????????????????????????????OutputStream?out=s.getOutputStream();????????????????????????????out.write("上傳成功!".getBytes());????????????????fos.close();????????????s.close();??????????}??????????catch?(Exception?e)??????????{??????????????throw?new?RuntimeException(ip+"圖片上傳失敗");??????????}??????}??}??
二、客戶端并發登錄
????????客戶端通過鍵盤錄入用戶名,服務端對這個用戶名進行校驗。
??????? 如果該用戶存在,在服務端顯示xxx,已登陸;并在客戶端顯示xxx,歡迎光臨。
??????? 如果用戶不存在,在服務端顯示xxx,嘗試登陸;并在客戶端顯示xxx,該用戶不存在。
??????? 最多就登錄三次。
代碼:?
[java]?view plaincopy
import?java.io.*;??import?java.net.*;??class??LoginClient??{??????public?static?void?main(String[]?args)?throws?Exception??????{??????????????????Socket?s=new?Socket("localhost",10000);??????????????????BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));??????????????????????????????PrintWriter?out?=new?PrintWriter(s.getOutputStream(),true?);????????????????????BufferedReader?in=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????String?line=null;????????????for(int?x=0;x<3;x++)??????????{??????????????line=br.readLine();????????????if?(line==null)??????????????{??????????????????break;????????????}????????????????out.println(line);??????????????String?info=in.readLine();??????????????System.out.println(info);????????????????if?(info.contains("歡迎"))????????????{??????????????????break;????????????}??????????}????????????br.close();????????s.close();??????}??}????class?LoginServer??{??????public?static?void?main(String?[]?args)throws?Exception??????{??????????????????ServerSocket?ss=new?ServerSocket(10000);????????????????????while?(true)??????????{??????????????????????????Socket?s=ss.accept();????????????????????????????????????new?Thread(new?LoginThread(s)).start();??????????}????????????????????????}??}????class?LoginThread?implements?Runnable??{??????private?Socket?s;??????LoginThread(Socket?s)??????{??????????this.s=s;??????}??????public?void?run()??????{??????????????????String?ip=s.getInetAddress().getHostAddress();??????????System.out.println(ip+"??connected.....");??????????try??????????{?????????????????????for?(int?x=0;x<3?;x++?)??????????????{?????????????????????????????????????BufferedReader?in=new?BufferedReader(new?InputStreamReader(s.getInputStream()));????????????????????????????????????????????????????BufferedReader?br=new?BufferedReader(new?FileReader("users.txt"));????????????????????String?line=in.readLine();????????????????if?(line==null)????????????????{??????????????????????break;????????????????}??????????????????String?data=null;??????????????????boolean?flag=false;????????????????????????????????while?((data=br.readLine())!=null)??????????????????{??????????????????????if?(line.equals(data))??????????????????????{??????????????????????????flag=true;????????????????????????break;??????????????????????}??????????????????}????????????????????????????????????PrintWriter?out=new?PrintWriter(s.getOutputStream(),true);????????????????????if?(flag)??????????????????{??????????????????????System.out.println(line+",已登陸!");????????????????????????????????????????????out.println(line+",歡迎光臨!");????????????????????????break;????????????????}??????????????????else??????????????????{??????????????????????System.out.println(line+",嘗試登陸!");??????????????????????out.println(line+",用戶名不存在!");??????????????????}?????????????????}??????????????s.close();????????}??????????catch?(Exception?e)??????????{??????????????throw?new?RuntimeException("用戶登陸失敗");??????????}?????????}??}??
三、客戶端和服務的瀏覽器演示
??????? 瀏覽器是一個標準的客戶端,它可以對服務端傳送過來的數據消息進行解析,把符合應用層協議的消息部分解析后,將頭信息拆包掉,傳送到應用層,只保留了正確的正文主題部分顯示在主體部分上。
??????? 而由于使用java編譯是在傳輸層和網際層處理的,所以,會接受到全部的消息,包含了頭消息。而瀏覽器處于應用層,已將發送來的頭消息去除,只留下了主體信息。
示例:
??????? 自定義服務器,用瀏覽器訪問:
[java]?view plaincopy
import?java.io.*;??import?java.net.*;????class??ServerDemo??{??????public?static?void?main(String[]?args)throws?Exception???????{??????????????????ServerSocket?ss=new?ServerSocket(10000);??????????????????Socket?s=ss.accept();??????????????????String?ip=s.getInetAddress().getHostAddress();????????????System.out.println(ip);??????????????????InputStream?in=s.getInputStream();????????????byte[]?buf=new?byte[1024];??????????int?len=in.read(buf);??????????????????System.out.println(new?String(buf,0,len));??????????????????PrintWriter?out=new?PrintWriter(s.getOutputStream(),true);??????????out.println("<font?color='red'?size='7'>客戶端你好!</font>");????????????s.close();????????ss.close();??????}??}?? ?
四、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
??import?java.io.*;??import?java.awt.*;??import?java.awt.event.*;??import?java.net.*;????class?MyIEGUIDemo??{??????????private?Frame?f;??????private?Button?but,bok;??????private?TextField?tf;??????private?TextArea?ta;????????????MyIEGUIDemo()??????{??????????init();??????}????????????public?void?init()??????{??????????????????f=new?Frame("我的Window");??????????but=new?Button("跳轉");??????????tf=new?TextField(50);??????????ta=new?TextArea(25,60);????????????????????f.setBounds(300,150,500,500);??????????f.setLayout(new?FlowLayout());????????????????????f.add(tf);??????????f.add(but);??????????f.add(ta);????????????????????myEvent();????????????????????f.setVisible(true);??????}????????????public?void?myEvent()??????{??????????????????f.addWindowListener(new?WindowAdapter()??????????{??????????????public?void?windowClosing(WindowEvent?e)??????????????{??????????????????System.exit(0);??????????????}??????????});????????????????????but.addActionListener(new?ActionListener()??????????{??????????????public?void?actionPerformed(ActionEvent?e)??????????????{??????????????????showFile();????????????}??????????});????????????????????????????????tf.addKeyListener(new?KeyAdapter()??????????{??????????????public?void?keyPressed(KeyEvent?e)??????????????{??????????????????????????????????if(e.getKeyCode()==KeyEvent.VK_ENTER)??????????????????????showFile();??????????????}??????????});??????}????????????????private?void?showFile()??????????{??????????????ta.setText("");??????????????String?path=tf.getText();????????????try??????????????{??????????????????URL?url?=new?URL(path);??連接網頁服務器??????????????????URLConnection?conn=url.openConnection();??????????????????????????????????InputStream?in=conn.getInputStream();????????????????????byte[]?buf=new?byte[1024*1024];????????????????????int?len=in.read(buf);??????????????????????????????????ta.append(new?String(buf,0,len));??????????????}??????????????catch?(Exception?e)??????????????{??????????????????throw?new?RuntimeException("連接"+path+"網站失敗");??????????????}??????????}????????public?static?void?main(String[]?args)???????{??????????????????new?MyIEGUIDemo();??????}??}?? ?
小知識點
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
總結
以上是生活随笔為你收集整理的Java基础---网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。