Java知多少(105)套接字(Socket)
網絡應用模式主要有:
- 主機/終端模式:集中計算,集中管理;
- 客戶機/服務器(Client/Server,簡稱C/S)模式:分布計算,分布管理;
- 瀏覽器/服務器模式:利用Internet跨平臺。
www(萬維網)就是建立在客戶機/服務器模式上,以HTML語言和HTTP協議為基礎,能夠提供各種Internet服務的信息瀏覽系統。網絡信息放在主機的不同位置,www服務器利用超文本鏈路鏈接各項信息。www客戶機(瀏覽器Brower)負責與服務器建立聯系,向服務器發送請求,處理HTML超媒體,提供圖形用戶界面(GUI),顯示信息等。
在客戶機/服務器工作模式中,在Server端,要準備接受多個Client端計算機的通信。為此,除用IP地址標識Internet上的計算機之外,另還引入端口號,用端口號標識正在Server端后臺服務的線程。端口號與IP地址的組合稱為網絡套接字(socket)。
Java語言在實現C/S模式中,套接字分為兩類:
- 在Server端,ServerSocket類支持底層的網絡通信;
- 在Client端,Socket類支持網絡的底層通信。
Server機通過端口(總線I/O地址)提供面向Client機的服務;Server機在它的幾個不同端口分別同時提供幾種不同的服務。Client接入Server的某一端口,通過這個端口提請Server機為其服務。規定:端口號0~1023供系統專用。例如,HTTP協議在端口80,telnet協議在端口23。端口1024~65535供應用程序使用。
當Client程序和Server程序需要通信時,可以用Socket類建立套接字連接。套接字連接可想象為一個電話呼叫:最初是Client程序建立呼叫,Server程序監聽;呼叫完成后,任何一方都可以隨時講話。
雙方實現通信有流式socket和數據報式socket兩種可選方式:
- 流式socket是有連接的通信,即TCP(Transmission Control Protocol):每次通信前建立連接,通信結束后斷開連接。特點是可以保證傳輸的正確性、可靠性。
- 數據報式socket是無連接的通信,即UDP(User Datagram Protocol):將欲傳輸的數據分成 小包,直接上網發送。無需建立連接和拆除連接,速度快,但無可靠保證。
流式socket在Client程序和Server程序間建立通信的通道。每個socket可以進行讀和寫兩種操作。對于任一端,與對方的通信會話過程是:
建立socket連接,獲得輸入/輸出流,讀數據/寫數據,通信完成后關閉socket(拆除連接)。流式Socket的通信過程見【例 13-1】。
利用socket的構造方法,可以在客戶端建立到服務器的套接字對象:
? ? Socket(String host,int port):host是服務器的IP地址,port是端口號,這些是預先約定的。
例如,代碼:
然后,用getInputStream()方法獲得輸入流,用這個輸入流讀取服務器放入“線路”的信息;用getOutputStream()方法獲得輸出流,用這個輸出流將信息寫入“線路”。
利用ServerSocket的構造方法可以在服務器建立接受客戶套接字的服務器套接字對象:
服務器端程序在指定的端口監聽,當收到Client程序發出的服務請求時,創建一個套接字對象與該端口對應的Client程序通信。例如,執行上述建立服務器套接字對象的代碼,確立了對象serverSocket后,就可能它使用accept()方法,得到Socket對象,接收Client程序來自套接字mySocket的信息。如以下代碼所示:
try{Socket sc = serverSocket.accept();//ac是一個Socket對象}catch(IOException e){} 要撤銷服務,可以關閉Socket對象sc:sc.close();【例 13-3】C/S模式中的Client端應用程序。這是一個Client端的流式Socket通信的簡單實例,代碼說明Client端程序的編寫方法。例中,Client程序向服務器主機的端口4441提出請求,連接建立后完成對服務器的讀寫。
1 import java.io.*; 2 import java.net.*; 3 public class Client{ 4 public static void main(String args[]){ 5 String s = null;Socket mySocket; 6 DataInputStream in = null;DataOutputStream out = null; 7 try{ 8 mySocket = new Socket(“localhost”,4441); 9 in = new DataInputStream(mySocket.getInputStream()); 10 out = new DataOutputStream(mySocket.getOutputStream()); 11 out.writeUTF(“good server!”); 12 while(true){ 13 s = in.readUTF(); 14 if(s==null) break; 15 else System.out.println(s); 16 } 17 mySocket.close(); 18 }catch(IOException e){ 19 System.out.println(“can’t connect”); 20 } 21 } 22 }【例 13-4】與例10.3 Client端應用程序對應的Server端應用程序。程序在4441端口監聽,當檢測到有客戶機請求時,產生一個內為“客戶,你好,我是服務器”的字符串輸出到客戶端。
1 import java.io.*;import java.net.*; 2 public class Server{ 3 public static void main(String args[]){ 4 ServerSocket server = null; 5 Socket you = null;String s = null; 6 DataOutputStream out = null; 7 DataInputStream in = null; 8 try{ 9 server = new ServerSocket(4441); 10 }catch(IOException e1){ 11 system.out.println(“ERROR:” +e1); 12 } 13 try{ 14 you = server.accept(); 15 in = new DataInputStream(you.getInputStream()); 16 out = new DataOutputStream(you. getOutputStream()); 17 while(true){ 18 s = in.readUTF(); 19 if(s!=null) break; 20 } 21 out.writeUTF(“客戶,你好,我是服務器”); 22 out.close(); 23 } 24 catch(IOException e){System.out.println(“ERROR:”+e);} 25 } 26 }為了充分發揮計算機的平行工作能力,可以把套接字連接工作讓一個線程完成。當客戶端要請求服務器給予服務,或當服務器端接收到一個客戶的服務請求,就啟動一個專門完成信息通信的線程,在該線程中創建輸入輸出流,并完成客戶端與服務器端的信息交流。
【例 13-5】 將套接字連接工作置于線程的客戶端小應用程序。界面在有一個發送信息按紐、一個文本框和一個文本區。客戶端應用程序首先與服務器建立套接字連接。使用數據輸入流in反復讀取服務器放入線路里的信息,將收到的信息在文本區中顯示。婐志取的信息是“結束”,則關閉套接字連接,并結束程序。用戶也可在文本框輸入信息,并按發送信息按鈕,則客戶端程序利用數據輸出流out,將文本框中的內容發送給服務器。
【例 13-6】對應例10.5客戶端小應用程序的服務器端小應用程序。程序以端4441建立與客戶端的套接字連接,服務器端收到客戶端的申請后,以客戶的套接字建立一個線程,并啟動。如果沒有客戶申請,則繼續監聽客戶的申請。線程按客戶的套接字建立輸入數據流in和輸數據流out。線程利用in讀取客戶放入線路里的信息。如果接受的信息是“結束”,則服務器回復“結束”后關閉套接字連接;否則回復:“我是服務器你對我說“,以及服務器接收到的信息。
1 import java.net.*; 2 import java.io.*; 3 import java.awt.*; 4 import javax.swing.*; 5 import java.awt.event.*; 6 import java.applet.*; 7 public class Aclient extends Applet implements Runnable,ActionListener{ 8 JButton button; JTextField textF; JTextArea textA; 9 Socket socket; Thread thread; 10 DataInputStream in; DataOutputStream out; 11 public void init(){ 12 setBackground(new Color(120,153,137)); 13 setLayout(new BorderLayout()); 14 Button = new JButton(“發送信息”); 15 textF = new JTextField(20); 16 textA = new JTextArea(20,30); 17 setSize(450,350); 18 JPanel p = new JPanel(); 19 p.add(textF); p.add(button); 20 add(textA,”Center”); add(p,”South”); 21 button.addActionListener(this); 22 } 23 public void start(){ 24 try{ 25 socket = new Socket(this.getCodeBase().getHost(),4441); 26 in = new DataInputStream(socket.getInputStream()); 27 out = new DataOutputStream(socket.getOutputStream()); 28 }catch(IOException e){} 29 if(thread==null){ 30 thread = new Thread(this); 31 thread.setPriority(Thread.MIN_PRIORITY); 32 thread.start(); 33 } 34 } 35 public void run(){ 36 String s = null; 37 while(true){ 38 try{ 39 s = in.readUTF(); 40 }catch(IOException e){} 41 if(s.equals(“結束”)){ 42 try{ 43 socket.close();break; 44 }catch(IOException e){} 45 }else texA.append(s + “\n”); 46 } 47 } 48 public void actionPerformed(ActionEvent e){ 49 if(e.getSource()==button){ 50 String s = textF.getText(); 51 if(s! = null){ 52 try{ 53 out.writeUTF(s); 54 }catch(IOException e1){} 55 } 56 else{ 57 try{ 58 out.writeUTF(“請說話”); 59 }catch(IOException e1){} 60 } 61 } 62 } 63 }系列文章:
Java知多少(上) Java知多少(中) Java知多少(78)Java向量(Vector)及其應用 Java知多少(79)哈希表及其應用 Java知多少(80)圖形界面設計基礎 Java知多少(81)框架窗口基礎 Java知多少(82)標簽、按鈕和按鈕事件簡介 Java知多少(83)面板基礎:JPanel和JScrollPane Java知多少(84)圖形界面之布局設計 Java知多少(85)文本框和文本區 Java知多少(86)文本框和文本區的輸入輸出 Java知多少(87)選擇框和單選按鈕 Java知多少(88)列表和組合框 Java知多少(89)列表和組合框 Java知多少(90)菜單 Java知多少(91)對話框 Java知多少(92)滾動條 Java知多少(93)鼠標事件 Java知多少(94)鍵盤事件 Java知多少(95)繪圖基礎 Java知多少(96)繪圖之設置字型和顏色 Java知多少(97)繪圖模式概述 Java知多少(98)Graphics類的繪圖方法 Java知多少(99)Graphics2D類的繪圖方法 Java知多少(100)圖像處理基礎 Java知多少(101)圖像緩沖技術 Java知多少(102)多媒體基礎 Java知多少(103)網絡編程之IP地址和InetAddress類 Java知多少(104)網絡編程之統一資源定位符URL轉載于:https://www.cnblogs.com/Coda/p/4603758.html
總結
以上是生活随笔為你收集整理的Java知多少(105)套接字(Socket)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 孕妇梦到找不到家什么意思
- 下一篇: JavaWeb重要知识点总结