Java套接字(Socket)網(wǎng)絡編程入門
網(wǎng)絡應用模式主要有:
- 主機/終端模式:集中計算,集中管理;
- 客戶機/服務器(Client/Server,簡稱C/S)模式:分布計算,分布管理;
- 瀏覽器/服務器模式:利用Internet跨平臺。
www(萬維網(wǎng))就是建立在客戶機/服務器模式上,以HTML語言和HTTP協(xié)議為基礎(chǔ),能夠提供各種Internet服務的信息瀏覽系統(tǒng)。網(wǎng)絡信息放在主機的不同位置,www服務器利用超文本鏈路鏈接各項信息。www客戶機(瀏覽器Brower)負責與服務器建立聯(lián)系,向服務器發(fā)送請求,處理HTML超媒體,提供圖形用戶界面(GUI),顯示信息等。
在客戶機/服務器工作模式中,在Server端,要準備接受多個Client端計算機的通信。為此,除用IP地址標識Internet上的計算機之外,另還引入端口號,用端口號標識正在Server端后臺服務的線程。端口號與IP地址的組合稱為網(wǎng)絡套接字(socket)。
Java語言在實現(xiàn)C/S模式中,套接字分為兩類:
- 在Server端,ServerSocket類支持底層的網(wǎng)絡通信;
- 在Client端,Socket類支持網(wǎng)絡的底層通信。
Server機通過端口(總線I/O地址)提供面向Client機的服務;Server機在它的幾個不同端口分別同時提供幾種不同的服務。Client接入Server的某一端口,通過這個端口提請Server機為其服務。規(guī)定:端口號0~1023供系統(tǒng)專用。例如,HTTP協(xié)議在端口80,telnet協(xié)議在端口23。端口1024~65535供應用程序使用。
當Client程序和Server程序需要通信時,可以用Socket類建立套接字連接。套接字連接可想象為一個電話呼叫:最初是Client程序建立呼叫,Server程序監(jiān)聽;呼叫完成后,任何一方都可以隨時講話。
雙方實現(xiàn)通信有流式socket和數(shù)據(jù)報式socket兩種可選方式:
- 流式socket是有連接的通信,即TCP(Transmission Control Protocol):每次通信前建立連接,通信結(jié)束后斷開連接。特點是可以保證傳輸?shù)恼_性、可靠性。
- 數(shù)據(jù)報式socket是無連接的通信,即UDP(User Datagram Protocol):將欲傳輸?shù)臄?shù)據(jù)分成 小包,直接上網(wǎng)發(fā)送。無需建立連接和拆除連接,速度快,但無可靠保證。
流式socket在Client程序和Server程序間建立通信的通道。每個socket可以進行讀和寫兩種操作。對于任一端,與對方的通信會話過程是:
建立socket連接,獲得輸入/輸出流,讀數(shù)據(jù)/寫數(shù)據(jù),通信完成后關(guān)閉socket(拆除連接)。
利用socket的構(gòu)造方法,可以在客戶端建立到服務器的套接字對象:
Socket(String host,int port):host是服務器的IP地址,port是端口號,這些是預先約定的。
例如,代碼:
try{ Socket mySocket = new Socket(“http://www.weixueyuan.net” ,1860); }catch(IOException e){}
然后,用getInputStream()方法獲得輸入流,用這個輸入流讀取服務器放入“線路”的信息;用getOutputStream()方法獲得輸出流,用這個輸出流將信息寫入“線路”。
利用ServerSocket的構(gòu)造方法可以在服務器建立接受客戶套接字的服務器套接字對象:
ServerSocket(int port):指定端口號,創(chuàng)建一個ServerSocket對象。端口號port要與客戶呼叫的端口號相同。為此,用以下形式代碼:
try{ ServerSocket serverSocket = new ServerSocket(1860); }catch(IOException e){}
服務器端程序在指定的端口監(jiān)聽,當收到Client程序發(fā)出的服務請求時,創(chuàng)建一個套接字對象與該端口對應的Client程序通信。例如,執(zhí)行上述建立服務器套接字對象的代碼,確立了對象serverSocket后,就可能它使用accept()方法,得到Socket對象,接收Client程序來自套接字mySocket的信息。如以下代碼所示:
try{ Socket sc = serverSocket.accept();//ac是一個Socket對象 }catch(IOException e){}
要撤銷服務,可以關(guān)閉Socket對象sc:
sc.close();
【例】C/S模式中的Client端應用程序。這是一個Client端的流式Socket通信的簡單實例,代碼說明Client端程序的編寫方法。例中,Client程序向服務器主機的端口4441提出請求,連接建立后完成對服務器的讀寫。
import java.io.*; import java.net.*; public class Client{ public static void main(String args[]){ String s = null;Socket mySocket; DataInputStream in = null;DataOutputStream out = null; try{ mySocket = new Socket(“l(fā)ocalhost”,4441); in = new DataInputStream(mySocket.getInputStream()); out = new DataOutputStream(mySocket.getOutputStream()); out.writeUTF(“good server!”); while(true){ s = in.readUTF(); if(s==null) break; else System.out.println(s); } mySocket.close(); }catch(IOException e){ System.out.println(“can't connect”); } } }
【例】與Client端應用程序?qū)腟erver端應用程序。程序在4441端口監(jiān)聽,當檢測到有客戶機請求時,產(chǎn)生一個內(nèi)為“客戶,你好,我是服務器”的字符串輸出到客戶端。
import java.io.*;import java.net.*; public class Server{ public static void main(String args[]){ ServerSocket server = null; Socket you = null;String s = null; DataOutputStream out = null; DataInputStream in = null; try{ server = new ServerSocket(4441); }catch(IOException e1){ system.out.println(“ERROR:” +e1); } try{ you = server.accept(); in = new DataInputStream(you.getInputStream()); out = new DataOutputStream(you. getOutputStream()); while(true){ s = in.readUTF(); if(s!=null) break; } out.writeUTF(“客戶,你好,我是服務器”); out.close(); } catch(IOException e){System.out.println(“ERROR:”+e);} } }
為了充分發(fā)揮計算機的平行工作能力,可以把套接字連接工作讓一個線程完成。當客戶端要請求服務器給予服務,或當服務器端接收到一個客戶的服務請求,就啟動一個專門完成信息通信的線程,在該線程中創(chuàng)建輸入輸出流,并完成客戶端與服務器端的信息交流。
【例】 將套接字連接工作置于線程的客戶端小應用程序。界面在有一個發(fā)送信息按紐、一個文本框和一個文本區(qū)??蛻舳藨贸绦蚴紫扰c服務器建立套接字連接。使用數(shù)據(jù)輸入流in反復讀取服務器放入線路里的信息,將收到的信息在文本區(qū)中顯示。婐志取的信息是“結(jié)束”,則關(guān)閉套接字連接,并結(jié)束程序。用戶也可在文本框輸入信息,并按發(fā)送信息按鈕,則客戶端程序利用數(shù)據(jù)輸出流out,將文本框中的內(nèi)容發(fā)送給服務器。
import java.net.*; import java.io.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.applet.*; public class Aclient extends Applet implements Runnable,ActionListener{ JButton button; JTextField textF; JTextArea textA; Socket socket; Thread thread; DataInputStream in; DataOutputStream out; public void init(){ setBackground(new Color(120,153,137)); setLayout(new BorderLayout()); Button = new JButton(“發(fā)送信息”); textF = new JTextField(20); textA = new JTextArea(20,30); setSize(450,350); JPanel p = new JPanel(); p.add(textF); p.add(button); add(textA,”Center”); add(p,”South”); button.addActionListener(this); } public void start(){ try{ socket = new Socket(this.getCodeBase().getHost(),4441); in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); }catch(IOException e){} if(thread==null){ thread = new Thread(this); thread.setPriority(Thread.MIN_PRIORITY); thread.start(); } } public void run(){ String s = null; while(true){ try{ s = in.readUTF(); }catch(IOException e){} if(s.equals(“結(jié)束”)){ try{ socket.close();break; }catch(IOException e){} }else texA.append(s + “\n”); } } public void actionPerformed(ActionEvent e){ if(e.getSource()==button){ String s = textF.getText(); if(s! = null){ try{ out.writeUTF(s); }catch(IOException e1){} } else{ try{ out.writeUTF(“請說話”); } catch(IOException e1){} } } } }
【例】程序以端4441建立與客戶端的套接字連接,服務器端收到客戶端的申請后,以客戶的套接字建立一個線程,并啟動。如果沒有客戶申請,則繼續(xù)監(jiān)聽客戶的申請。線程按客戶的套接字建立輸入數(shù)據(jù)流in和輸數(shù)據(jù)流out。線程利用in讀取客戶放入線路里的信息。如果接受的信息是“結(jié)束”,則服務器回復“結(jié)束”后關(guān)閉套接字連接;否則回復:“我是服務器你對我說“,以及服務器接收到的信息。
import java.net.*; import java.io.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.applet.*; public class Aclient extends Applet implements Runnable,ActionListener{ JButton button; JTextField textF; JTextArea textA; Socket socket; Thread thread; DataInputStream in; DataOutputStream out; public void init(){ setBackground(new Color(120,153,137)); setLayout(new BorderLayout()); Button = new JButton(“發(fā)送信息”); textF = new JTextField(20); textA = new JTextArea(20,30); setSize(450,350); JPanel p = new JPanel(); p.add(textF); p.add(button); add(textA,”Center”); add(p,”South”); button.addActionListener(this); } public void start(){ try{ socket = new Socket(this.getCodeBase().getHost(),4441); in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); }catch(IOException e){} if(thread==null){ thread = new Thread(this); thread.setPriority(Thread.MIN_PRIORITY); thread.start(); } } public void run(){ String s = null; while(true){ try{ s = in.readUTF(); }catch(IOException e){} if(s.equals(“結(jié)束”)){ try{ socket.close();break; }catch(IOException e){} }else texA.append(s + “\n”); } } public void actionPerformed(ActionEvent e){ if(e.getSource()==button){ String s = textF.getText(); if(s! = null){ try{ out.writeUTF(s); }catch(IOException e1){} } else{ try{ out.writeUTF(“請說話”); }catch(IOException e1){} } } } }
- Java 網(wǎng)絡編程socket編程等詳解
- Java基于Socket實現(xiàn)網(wǎng)絡編程實例詳解
- 簡單講解Java的Socket網(wǎng)絡編程的多播與廣播實現(xiàn)
- Java的Socket網(wǎng)絡編程基礎(chǔ)知識入門教程
- Java網(wǎng)絡編程基礎(chǔ)教程之Socket入門實例
- java網(wǎng)絡編程之socket網(wǎng)絡編程示例(服務器端/客戶端)
- Java網(wǎng)絡編程實現(xiàn)的簡單端口掃描器示例
- Java網(wǎng)絡編程教程之設(shè)置請求超時的方法
- Java網(wǎng)絡編程之TCP通信完整代碼示例
- 詳解Java網(wǎng)絡編程
相關(guān)文章
Java實戰(zhàn)之課程在線學習系統(tǒng)的實現(xiàn)
本文將采用SpringBoot+Spring+Mybatis+Thyeleaf實現(xiàn)一個課程在線學習系統(tǒng),采用SpringBoot框架實現(xiàn)?前臺模板用的thymeleaf數(shù)據(jù)庫層采用mybatis框架注解模式,感興趣的可以了解一下2022-04-04詳解Spring 兩種注入的方式(Set和構(gòu)造)實例
本篇文章主要介紹了Spring 兩種注入的方式(Set和構(gòu)造)實例,Spring框架主要提供了Set注入和構(gòu)造注入兩種依賴注入方式。有興趣的可以了解一下。2017-02-02關(guān)于idea的gitignore文件編寫及解決ignore文件不生效問題
這篇文章主要介紹了idea的gitignore文件編寫及解決ignore文件不生效問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Spring?Validation實現(xiàn)數(shù)據(jù)校驗的示例
Spring?Validation其實就是對Hibernate?Validator進一步的封裝,方便在Spring中使用,這篇文章主要介紹了Spring?Validation實現(xiàn)數(shù)據(jù)校驗的示例,需要的朋友可以參考下2023-03-03