




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
本章學習目標:●了解Java網絡相關的API●掌握Socket類及其方法的使用●掌握ServerSocket類的使用第十五章網絡編程第1節(jié)partJava網絡API
最初,Java就是作為網絡編程語言而出現(xiàn)的,其本身就對網絡通信提供了支持,允許使用網絡上的各種資源和數(shù)據,與服務器建立各種傳輸通道,實現(xiàn)數(shù)據的傳輸,使網絡編程實現(xiàn)起來變得簡單。Java中有關網絡方面的功能都定義在包中,該包下的URL和URLConnection等類提供了以程序的方式來訪問Web服務,而URLDecoder和URLEncoder則提供了普通字符串和application/x-www-form-urlencodeMIME字符串相互轉換的靜態(tài)方法。Java網絡API本節(jié)概述Java提供InetAddress類來封裝IP地址或域名,InetAddress類有兩個子類:Inet4Address類和Inet6Address類,分別用于封裝4個字節(jié)的IP地址和6個字節(jié)的IP地址。InetAddress內部對地址數(shù)字進行隱藏,用戶不需要了解實現(xiàn)地址的細節(jié),只需了解如何調用相應的方法即可。InetAddress類無構造方法,因此不能直接創(chuàng)建其對象,而是通過該類的靜態(tài)方法創(chuàng)建一個InetAddress對象或InetAddress數(shù)組。InetAddress類常用方法如表15-1所示。表15-1InetAddress類常用方法15.1.1InetAddress類InetAddress類下述案例示例了InetAddress類的使用,代碼如下所示?!敬a15.1】InetAddressExample.javapackagecom;importjava.io.IOException;import.InetAddress;import.UnknownHostException;publicclassInetAddressExample{ publicstaticvoidmain(String[]args){ try{ //獲取本機地址信息 InetAddresslocalIp=InetAddress.getLocalHost(); System.out.println("localIp.getCanonicalHostName()=" +localIp.getCanonicalHostName()); System.out.println("localIp.getHostAddress()=" +localIp.getHostAddress()); System.out.println("localIp.getHostName()=" +localIp.getHostName()); System.out.println("localIp.toString()=" +localIp.toString()); System.out.println("localIp.isReachable(5000)=“+localIp.isReachable(5000)); System.out.println("--------------");InetAddress類15.1.1 //獲取指定域名地址信息 InetAddressbaiduIp=InetAddress.getByName(""); System.out.println("baiduIp.getCanonicalHostName()=" +baiduIp.getCanonicalHostName()); System.out.println("baiduIp.getHostAddress()=" +baiduIp.getHostAddress()); System.out.println("baiduIp.getHostName()=" +baiduIp.getHostName()); System.out.println("baiduIp.toString()=" +baiduIp.toString()); System.out.println("baiduIp.isReachable(5000)=" +baiduIp.isReachable(5000)); System.out.println("-----------------"); //獲取指定原始IP地址信息 InetAddressip=InetAddress.getByAddress(newbyte[]{127,0,0,1}); //InetAddressip=InetAddress.getByName(""); System.out.println("ip.getCanonicalHostName()=“+ip.getCanonicalHostName()); System.out.println("ip.getHostAddress()=“+ip.getHostAddress()); System.out.println("ip.getHostName()=“+ip.getHostName()); System.out.println("ip.toString()="+ ip.toString());InetAddress類15.1.1 System.out.println("ip.isReachable(5000)=“+ip.isReachable(5000)); }catch(UnknownHostExceptione){ e.printStackTrace(); }catch(Exceptione){ e.printStackTrace(); } }}InetAddress類
上述代碼分別獲取本機、指定域名以及指定IP地址的InetAddress對象。其中,調用getLocalHost()可以獲取本機InetAddress對象;調用getByName()可以獲取指定域名的InetAddress對象;調用getByAddress()可以獲取指定IP地址的InetAddress對象,該方法的參數(shù)使用字節(jié)數(shù)組存放IP地址。也可以直接通過getByName()獲取指定IP地址的InetAddress對象,此時,IP地址作為字符串即可。15.1.1程序運行結果如下所示:localIp.getCanonicalHostName()=01localIp.getHostAddress()=01localIp.getHostName()=shouchao-PClocalIp.toString()=shouchao-PC/01localIp.isReachable(5000)=true--------------baiduIp.getCanonicalHostName()=08baiduIp.getHostAddress()=08baiduIp.getHostName()=baiduIp.toString()=/08baiduIp.isReachable(5000)=false-----------------ip.getCanonicalHostName()=ip.getHostAddress()=ip.getHostName()=ip.toString()=/ip.isReachable(5000)=trueInetAddress類
需要注意的是:在獲得Internet上的域名所對應的地址信息時,需保證運行環(huán)境能訪問Internet,否則將拋出UnknownHostException異常。15.1.1URL(UniformResourceLocator,統(tǒng)一資源定位器)表示互聯(lián)網上某一資源的地址。資源可以是簡單的文件或目錄,也可以是對更為復雜對象的引用,例如對數(shù)據庫或搜索引擎的查詢。URL是最為直觀的一種網絡定位方法,符合人們的語言習慣,且容易記憶。在通常情況下,URL可以由協(xié)議名、主機、端口和資源四個部分組成,其語法格式如下所示:protocol://host:port/resourceName
其中:
●protocol是協(xié)議名,指明獲取資源所使用的傳輸協(xié)議,例如http、ftp等,并使用冒號“:”與其他部分進行隔離;
●host是主機名,指定獲取資源的域名,此部分由左邊的雙斜線“//”和右邊的單斜線“/”或可選冒號“:”限制;
●port是端口,指定服務的端口號,是一個可選參數(shù),由主機名左邊的冒號“:”和右邊的斜線“/”限制;
●resourceName是資源名,指定訪問的文件名或目錄。
例如:URL地址
:8080/student/index.jsp15.1.2URL類URL類
為了方便處理,Java將URL封裝成URL類,通過URL對象記錄下完整的URL信息。URL類常用方法及功能如表15-2所示。15.1.2URL類下述案例示例了根據指定的路徑構造URL對象,并獲取當前URL對象的相關屬性。代碼如下所示?!敬a15.2】URLExample.javapackagecom;import.MalformedURLException;import.URL;publicclassURLExample{publicstaticvoidmain(String[]args){ try{ URLmybook=newURL(":8080/student/index.jsp"); System.out.println("協(xié)議protocol="+mybook.getProtocol()); System.out.println("主機host="+mybook.getHost()); System.out.println("端口port="+mybook.getPort()); System.out.println("文件filename="+mybook.getFile()); System.out.println("錨ref="+mybook.getRef()); System.out.println("查詢信息query="+mybook.getQuery()); System.out.println("路徑path="+mybook.getPath()); }catch(MalformedURLExceptione){ e.printStackTrace(); }}}程序運行結果如下所示:協(xié)議protocol=http主機host=:8080端口port=-1文件filename=/student/index.jsp錨ref=null查詢信息query=null路徑path=/student/index.jsp15.1.2URL類URLConnection代表與URL指定的數(shù)據源的動態(tài)連接,該類提供一些比URL類更強大的服務器交互控制的方法,允許使用POST或PUT和其他HTTP請求方法將數(shù)據送回服務器。URLConnection是一個抽象類,其常用方法如表15-3所示。15.1.3URLConnection類URLConnection類下述案例示例了使用URLConnection類讀取網絡資源信息并打印,代碼如下所示。【代碼15.3】URLConnectionExample.javapackagecom;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;import.MalformedURLException;import.URL;import.URLConnection;publicclassURLConnectionExample{publicstaticvoidmain(String[]args){try{ //構建一URL對象 URLmybook=newURL("/"); //由URL對象獲取URLConnection對象 URLConnectionurlConn=mybook.openConnection();//設置請求屬性,字符集是UTF-8 urlConn.setRequestProperty("Charset","GBK"); //由URLConnection獲取輸入流,并構造BufferedReader對象 BufferedReaderbr=newBufferedReader(newInputStreamReader(urlConn.getInputStream()));15.1.3URLConnection類 StringinputLine; //循環(huán)讀取并打印數(shù)據 while((inputLine=br.readLine())!=null){ System.out.println(inputLine); } //關閉輸入流 br.close(); }catch(MalformedURLExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); }}}
上述代碼的運行結果是輸出指定網頁頁面的源代碼,此處不顯示輸出效果,讀者可以自己調試程序查看。15.1.3URLConnection類
當URL地址中包含非西歐字符時,系統(tǒng)會將這些非西歐字符轉換成特殊編碼(如“%XX”格式),此種編碼稱為application/x-www-form-urlencodedMIME。在編程過程中如果涉及到普通字符串和application/x-www-form-urlencodedMIME字符串之間相互轉換時,就需要使用URLDecoder和URLEncoder兩個工具類。
●URLDecoder工具類提供了一個decode(Strings,Stringenc)靜態(tài)方法,該方法將application/x-www-form-urlencodedMIME字符串轉換成普通字符串;
●URLEncoder工具類提供了一個encode(Strings,Stringenc)靜態(tài)方法,該方法與decode()方法正好相反,能夠將普通的字符串轉換成application/x-www-form-urlencodedMIME字符串。15.1.4URLDecoder和URLEncoder類URLDecoder和URLEcoder類下述案例示例了URLDecoder和URLEncoder兩個工具類的使用,代碼如下所示?!敬a15.4】URLDecoderExample.javapackagecom;importjava.io.UnsupportedEncodingException;import.URLDecoder;import.URLEncoder;publicclassURLDecoderExample{ publicstaticvoidmain(String[]args){ try{ //將普通字符串轉換成application/x-www-form-urlencoded字符串 StringurlStr=URLEncoder.encode("面向對象程序設計Java","GBK"); System.out.println(urlStr); //將application/x-www-form-urlencoded字符串轉換成普通字符串 StringkeyWord=URLDecoder.decode( "%C3%E6%CF%F2%B6%D4%CF%F3%B3%CC%D0%F2%C9%E8%BC%C6Java","GBK"); System.out.println(keyWord); }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } }}程序運行結果如下:%C3%E6%CF%F2%B6%D4%CF%F3%B3%CC%D0%F2%C9%E8%BC%C6Java面向對象程序設計Java15.1.4URLDecoder和URLEncoder類第2節(jié)part基于TCP的網路編程TCP/IP通信協(xié)議是一種可靠的、雙向的、持續(xù)的、點對點的網絡協(xié)議。使用TCP/IP協(xié)議進行通信時,會在通信的兩端各建立一個Socket(套接字),從而在通信的兩端之間形成網絡虛擬鏈路,其通信原理如圖15.1所示。基于TCP的網路編程本節(jié)概述Java對基于TCP的網絡通信提供了封裝,使用Socket對象封裝了兩端的通信端口。Socket對象屏蔽了網絡的底層細節(jié),例如媒體類型、信息包的大小、網絡地址、信息的重發(fā)等。Socket允許應用程序將網絡連接當成一個IO流,既可以向流中寫數(shù)據,也可以從流中讀取數(shù)據。一個Socket對象可以用來建立Java的IO系統(tǒng)到Internet上的任何機器(包括本機)的程序連接。
包中提供了網絡編程所需的類,其中基于TCP協(xié)議的網絡編程主要使用下面兩種Socket:
●ServerSocket:是服務器套接字,用于監(jiān)聽并接收來自客戶端的Socket連接;
●Socket:是客戶端套接字,用于實現(xiàn)兩臺計算機之間的通信?;赥CP的網路編程15.2.1Socket類
使用Socket套接字可以較為方便地在網絡上傳遞數(shù)據,從而實現(xiàn)兩臺計算機之間的通信。通??蛻舳耸褂肧ocket來連接指定的服務器,Socket的兩個常用構造方法如下:
●Socket(InetAddress|Stringhost,intport):創(chuàng)建連接到指定遠程主機和端口號的Socket對象,該構造方法沒有指定本地地址和本地端口號,默認使用本地主機IP地址和系統(tǒng)動態(tài)分配的端口;
●Socket(InetAddress|Stringhost,intport,InetAddresslocalAddr,intlocalPort):創(chuàng)建連接到指定遠程主機和端口號的Socket對象,并指定本地IP地址和本地端口號,適用于本地主機有多個IP地址的情況。
需要注意的是:上述兩個Socket構造方法都聲明拋出IOException異常,因此在創(chuàng)建Socket對象必須捕獲或拋出異常。端口號建議采用注冊端口(范圍是1024~49151之間的數(shù)),通常應用程序使用該范圍內的端口,以防止發(fā)生沖突。Socket類
例如:創(chuàng)建Socket對象try{Sockets=newSocket("28",9999);...//Socket通信}catch(IOExceptione){e.printStackTrace();}
除了構造方法,Socket類常用的其他方法如表15-4所示。15.2.1Socket類
通常使用Socket進行網絡通信的具體步驟如下:
①根據指定IP地址和端口號創(chuàng)建一個Socket對象;
②調用getInputStream()方法或getOutputStream()方法打開連接到Socket的輸入/輸出流;
③客戶端與服務器根據協(xié)議進行交互,直到關閉連接;
④關閉客戶端的Socket。
下述案例示例了創(chuàng)建客戶端Socket的過程,代碼如下所示。15.2.1Socket類【代碼15.5】ClientSocketExample.javapackagecom;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintStream;import.Socket;import.UnknownHostException;publicclassClientSocketExample{publicstaticvoidmain(String[]args){try{ //創(chuàng)建連接到本機、端口為9999的Socket對象 Socketsocket=newSocket("",9999); //將Socket對應的輸出流包裝成PrintStream PrintStreamps=newPrintStream(socket.getOutputStream()); //往服務器發(fā)送信息 ps.println("我喜歡Java"); ps.flush(); //將Socket對應的輸入流包裝成BufferedReader BufferedReaderbr=newBufferedReader(newInputStreamReader(socket.getInputStream()));15.2.1Socket類 //讀服務器返回的信息并顯示 Stringline=br.readLine(); System.out.println("來自服務器的數(shù)據:"+line); //關閉 br.close(); ps.close(); socket.close(); }catch(UnknownHostExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); }}}
上述代碼先創(chuàng)建了一個連接到本機、端口為9999的Socket對象;再使用getOutputStream()獲取Socket對象的輸出流,用于往服務器發(fā)送信息;然后使用getInputStream()獲取Socket對象的輸入流,讀取服務器返回的數(shù)據;最后關閉輸入/輸出流和Socket連接,釋放所有的資源。15.2.1Socket類15.2.2ServletSocket類ServerSocket是服務器套接字,運行在服務器端,通過指定端口主動監(jiān)聽來自客戶端的Socket連接。當客戶端發(fā)送Socket請求并與服務器端建立連接時,服務器將驗證并接收客戶端的Socket,從而建立客戶端與服務器之間的網絡虛擬鏈路;一旦兩端的實體之間建立了虛擬鏈路,就可以相互傳送數(shù)據。ServerSocket類常用的構造方法如下:
●ServerSocket(intport):根據指定端口來創(chuàng)建一個ServerSocket對象;
●ServerSocket(intport,intbacklog):創(chuàng)建一個ServerSocket對象,指定端口和連接隊列長度,此時增加一個用來改變連接隊列長度的參數(shù)backlog;
●ServerSocket(intport,intbacklog,InetAddresslocalAddr):創(chuàng)建一個ServerSocket對象,指定端口、連接隊列長度和IP地址;當機器擁有多個IP地址時,才允許使用localAddr參數(shù)指定具體的IP地址。ServletSocket類
需要注意的是:ServerSocket類的構造方法都聲明拋出IOException異常,因此在創(chuàng)建ServerSocket對象必須捕獲或拋出異常。另外,在選擇端口號時,建議選擇注冊端口(范圍是1024~49151的數(shù)),通常應用程序使用這個范圍內的端口,以防止發(fā)生沖突。
下面幾行代碼示例了創(chuàng)建一個ServerSocket對象:try{ ServerSocketserver=newServerSocket(9999);}catch(IOExceptione){ e.printStackTrace();}ServerSocket類常用的其他方法如表15-5所示。15.2.2ServletSocket類通常使用ServerSocket進行網絡通信的具體步驟如下:①根據指定的端口號來實例化一個ServerSocket對象;②調用ServerSocket對象的accept()方法接收客戶端發(fā)送的Socket對象;③調用Socket對象的getInputStream()/getOutputStream()方法來建立與客戶端進行交互的IO流;④服務器與客戶端根據一定的協(xié)議交互,直到關閉連接;⑤關閉服務器端的Socket;⑥回到第2步,繼續(xù)監(jiān)聽下一次客戶端發(fā)送的Socket請求連接。下述案例示例了創(chuàng)建服務器端ServerSocket的過程,代碼如下所示。15.2.2ServletSocket類【15.6】ServerSocketExample.javapackagecom;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintStream;import.ServerSocket;import.Socket;publicclassServerSocketExampleextendsThread{ //聲明一個ServerSocket ServerSocketserver; //計數(shù) intnum=0; publicServerSocketExample(){ //創(chuàng)建ServerSocket,用于監(jiān)聽9999端口是否有客戶端的Socket try{ server=newServerSocket(9999); }catch(IOExceptione){ e.printStackTrace(); }15.2.2ServletSocket類 //啟動當前線程,即執(zhí)行run()方法 this.start(); System.out.println("服務器啟動..."); } publicvoidrun(){ while(this.isAlive()){ try{ //接收客戶端的Socket Socketsocket=server.accept(); //將Socket對應的輸入流包裝成BufferedReader BufferedReaderbr=newBufferedReader(newInputStreamReader( socket.getInputStream())); //讀客戶端發(fā)送的信息并顯示 Stringline=br.readLine(); System.out.println(line); //將Socket對應的輸出流包裝成PrintStream PrintStreamps=newPrintStream(socket.getOutputStream()); //往客戶端發(fā)送信息 ps.println("您是第"+(++num)+"個訪問服務器的用戶!"); ps.flush();15.2.2ServletSocket類 //關閉 br.close(); ps.close(); socket.close(); }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } } publicstaticvoidmain(String[]args){ newServerSocketExample(); }}15.2.2ServletSocket類
上述代碼服務器端是一個多線程應用程序,能為多個客戶提供服務。在ServerSocketExample()構造方法中,先創(chuàng)建一個用于監(jiān)聽9999端口的ServerSocket對象,再調用this.start()方法啟動線程。在線程的run()方法中,先調用ServerSocket對象的accept()方法來接收客戶端發(fā)送的Socket對象;再使用getInputStream()獲取Socket對象的輸入流,用于讀取客戶端發(fā)送的數(shù)據信息;然后使用getOutputStream()獲取Socket對象的輸出流,往客戶端發(fā)送信息;最后關閉輸入、輸出流和Socket,釋放所有資源。
前面編寫的客戶端程序ClientSocketExample與服務器端程序ServerSocketExample能夠形成網絡通信,運行時先運行服務器端ServerSocketExample應用程序,服務器端先顯示如下提示:
服務器啟動...
然后,運行客戶端ClientSocketExample應用程序,此時服務器端又會增加打印一條信息:
我喜歡Java
客戶端應用程序會顯示:
來自服務器的數(shù)據:您是第1個訪問服務器的用戶!15.2.2ServletSocket類
一般服務器和客戶端之間,使用Socket進行基于C/S架構的網絡通信,程序設計的過程如下:
①服務器端通過某個端口監(jiān)聽是否有客戶端發(fā)送Socket連接請求;
②客戶端向服務器端發(fā)出一個Socket連接請求;
③服務器端調用accept()接收客戶端Socket并建立連接;
④通過調用Socket對象的getInputStream()/getOutputStream()方法進行IO流操作,服務器與客戶端之間進行信息交互;
⑤關閉服務器端和客戶端的Socket。15.2.2ServletSocket類15.2.3聊天室
基于TCP網絡編程的典型應用就是聊天室,下述內容使用Socket和ServerSocket實現(xiàn)多人聊天的聊天室程序。聊天室程序是基于C/S架構,分客戶端代碼和服務器端代碼。其中,客戶端是一個窗口應用程序,代碼如下。聊天室【代碼15.7】ChatClient.javapackagecom;importjava.awt.BorderLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintWriter;import.Socket;import.UnknownHostException;importjavax.swing.*;//聊天室客戶端publicclassChatClientextendsJFrame{ Socketsocket; PrintWriterpWriter; BufferedReaderbReader; JPanelpanel; JScrollPanesPane; JTextAreatxtContent;15.2.3聊天室 JLabellblName,lblSend; JTextFieldtxtName,txtSend; JButtonbtnSend; publicChatClient(){ super("聊天室"); txtContent=newJTextArea(); //設置文本域只讀 txtContent.setEditable(false); sPane=newJScrollPane(txtContent); lblName=newJLabel("昵稱:"); txtName=newJTextField(5); lblSend=newJLabel("發(fā)言:"); txtSend=newJTextField(20); btnSend=newJButton("發(fā)送"); panel=newJPanel(); panel.add(lblName); panel.add(txtName); panel.add(lblSend); panel.add(txtSend); panel.add(btnSend);15.2.3聊天室 this.add(panel,BorderLayout.SOUTH); this.add(sPane); this.setSize(500,300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try{ //創(chuàng)建一個套接字 socket=newSocket("",9999); //創(chuàng)建一個往套接字中寫數(shù)據的管道,即輸出流,給服務器發(fā)送信息 pWriter=newPrintWriter(socket.getOutputStream()); //創(chuàng)建一個從套接字讀數(shù)據的管道,即輸入流,讀服務器的返回信息 bReader=newBufferedReader( newInputStreamReader(socket.getInputStream())); }catch(UnknownHostExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); } //注冊監(jiān)聽 btnSend.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){15.2.3聊天室 //獲取用戶輸入的文本 StringstrName=txtName.getText(); StringstrMsg=txtSend.getText(); if(!strMsg.equals("")){ //通過輸出流將數(shù)據發(fā)送給服務器 pWriter.println(strName+"說:"+strMsg); pWriter.flush(); //清空文本框 txtSend.setText(""); } } }); //啟動線程 newGetMsgFromServer().start(); } //接收服務器的返回信息的線程 classGetMsgFromServerextendsThread{ publicvoidrun(){ while(this.isAlive()){ try{15.2.3聊天室 StringstrMsg=bReader.readLine(); if(strMsg!=null){ //在文本域中顯示聊天信息 txtContent.append(strMsg+"\n"); } Thread.sleep(50); }catch(Exceptione){ e.printStackTrace(); } } } } publicstaticvoidmain(Stringargs[]){ //創(chuàng)建聊天室客戶端窗口實例,并顯示 newChatClient().setVisible(true); }}15.2.3聊天室
上述代碼在構造方法中先創(chuàng)建客戶端圖形界面,并創(chuàng)建一個Socket對象連接服務器,然后獲取Socket對象的輸入流和輸出流,用于與服務器進行信息交互,輸出流可以給服務器發(fā)送信息,輸入流可以讀取服務器的返回信息。再對“發(fā)送”按鈕添加監(jiān)聽事件處理,當用戶單擊“發(fā)送”按鈕時,將用戶在文本框中輸入的數(shù)據通過輸出流寫到Socket中,實現(xiàn)將信息發(fā)送給服務器。GetMsgFromServer是一個用于不斷循環(huán)接收服務器的返回信息的線程,只要接收到服務器的信息,就將該信息在窗口的文本域中顯示。注意在構造方法的最后創(chuàng)建一個GetMsgFromServer線程實例并啟動。
聊天室的服務器端代碼如下所示。15.2.3聊天室【代碼15.8】ChatServer.javapackagecom;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintWriter;import.ServerSocket;import.Socket;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Date;importjava.util.LinkedList;//聊天室服務器端publicclassChatServer{ //聲明服務器端套接字ServerSocket ServerSocketserverSocket; //輸入流列表集合 ArrayList<BufferedReader>bReaders=newArrayList<BufferedReader>(); //輸出流列表集合 ArrayList<PrintWriter>pWriters=newArrayList<PrintWriter>();15.2.3聊天室 //聊天信息鏈表集合 LinkedList<String>msgList=newLinkedList<String>(); publicChatServer(){ try{ //創(chuàng)建服務器端套接字ServerSocket,在28888端口監(jiān)聽 serverSocket=newServerSocket(9999); }catch(IOExceptione){ e.printStackTrace(); } //創(chuàng)建接收客戶端Socket的線程實例,并啟動 newAcceptSocketThread().start(); //創(chuàng)建給客戶端發(fā)送信息的線程實例,并啟動 newSendMsgToClient().start(); System.out.println("服務器已啟動..."); } //接收客戶端Socket套接字線程 classAcceptSocketThreadextendsThread{ publicvoidrun(){ while(this.isAlive()){ try{15.2.3聊天室 //接收一個客戶端Socket對象 Socketsocket=serverSocket.accept(); //建立該客戶端的通信管道 if(socket!=null){ //獲取Socket對象的輸入流 BufferedReaderbReader=newBufferedReader( newInputStreamReader(socket.getInputStream())); //將輸入流添加到輸入流列表集合中 bReaders.add(bReader); //開啟一個線程接收該客戶端的聊天信息 newGetMsgFromClient(bReader).start(); //獲取Socket對象的輸出流,并添加到輸入出流列表集合中 pWriters.add(newPrintWriter(socket.getOutputStream())); } }catch(IOExceptione){ e.printStackTrace(); } } } }15.2.3聊天室//接收客戶端的聊天信息的線程classGetMsgFromClientextendsThread{BufferedReaderbReade
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年拉薩貨運從業(yè)資格證考試試題及答案解析
- 保障性合同范本
- 區(qū)域總經理合同范本
- 醫(yī)療就業(yè)合同范本
- 包食堂合同范本
- 促銷活動場地出租合同范本
- 農村電商合同范本
- 利用合同范本
- 前廳接待勞務合同范本
- 5人合作合同范本
- 2025屆新高考生物精準復習+提高農作物產量
- 第6課歐洲的思想解放運動教學設計2023-2024學年中職高一下學期高教版(2023)世界歷史
- 2024年云南省昆明市選調生考試(公共基礎知識)綜合能力題庫必考題
- 2024年時政試題庫(奪分金卷)
- 2024年江蘇農林職業(yè)技術學院單招職業(yè)適應性測試題庫及答案1套
- 工程項目移交方案
- 2024年湖南高速鐵路職業(yè)技術學院單招職業(yè)適應性測試題庫參考答案
- 腎性高血壓的護理
- 《帶電作業(yè)用絕緣工具試驗導則》
- 2024年時事政治熱點題庫200道附完整答案【必刷】
- 中國歷史地理概況智慧樹知到期末考試答案章節(jié)答案2024年復旦大學
評論
0/150
提交評論