1. 程式人生 > >網路程式設計socket類

網路程式設計socket類

通訊要素

  • ip + 埠號
  • 傳輸協議

TCP/IP協議簇

  • ip協議
    • 計算機網路地址定位協議
    • IP(Internet Protocol)協議是網路層的主要協議,支援網間互連的資料通訊
  • tcp協議/udp協議,實際使用協議
    • 傳輸協議
    • TCP/IP協議模型從更實用的角度出發,形成了高效的四層體系結構,即物理鏈路層、IP層、傳輸層和應用層。
    • 區別:
tcp/udp tcp udp
通道 使用TCP協議前,須先建立TCP連線,形成傳輸資料通道 將資料、源、目的封裝成資料包,不需要建立連線
可靠性 傳輸前,採用“三次握手”方式,是可靠的 因無需連線,故是不可靠的
節點 TCP協議進行通訊的兩個應用程序:客戶端、服務端
傳輸 在連線中可進行大資料量的傳輸 每個資料報的大小限制在64K內
效率 傳輸完畢,需釋放已建立的連線,效率低 傳送資料結束時無需釋放資源,速度快
應用 傳輸檔案,壓縮包,等不可破環的檔案 視訊,直播,語音等缺少一兩個位元組仍沒關係的
  • OSI參考模型:模型過於理想化,未能在因特網上進行廣泛推廣(各層有功能重疊現象)
OSI參考模型 TCP/IP參考模型 TCP/IP參考模型各層對應協議
應用層 應用層 HTTP、ftp、telnet、DNS…
表示層
會話層
傳輸層 傳輸層 TCP、UDP、…
網路層 網路層 IP、ICMP、ARP…
資料鏈路層 物理+資料鏈路層 Link

埠號

  • 埠號標識正在計算機上執行的程序(程式)
  • 不同的程序有不同的埠號
  • 被規定為一個 16 位的整數 0~65535。其中,0~1023被預先定義的服務通訊佔用(如MySql佔用埠3306,http佔用埠80等)。除非我們需要訪問這些特定服務,否則,就應該使用 1024~65535 這些埠中的某一個進行通訊,以免發生埠衝突
  • 理解,系統分配給應用對網路交流的匯流排地址,和埠繫結,當網路有資料傳來,系統通過埠號來傳給相應的應用
  • 埠號與IP地址的組合得出一個網路套接字

InetAddress類

  • 代表ip
  • Internet上的主機有兩種方式表示地址:
    • 域名(hostName):www.atguigu.com
    • IP 地址(hostAddress):202.108.35.210
  • InetAddress類主要表示IP地址,兩個子類:Inet4Address、Inet6Address。
  • InetAddress 類物件含有一個 Internet 主機地址的域名和IP地址:www.atguigu.com 和 202.108.35.210。
  • 域名容易記憶,當在連線網路時輸入一個主機的域名後,域名伺服器(DNS)負責將域名轉化成IP地址,這樣才能和主機建立連線。 -------域名解析
  • ip4: 4位元組編碼;ip6: 16位元組編碼,幾乎可以把網路上的一切進行編碼
  • 常用方法:
    • static InetAddress[] getAllByName(String host)根據host拿到ip序列
      • Given the name of a host, returns an array of its IP addresses, based on the configured name service on the system.
    • static InetAddress getByName(String host) 獲取ip
      • Determines the IP address of a host, given the host's name.
    • String getHostName() 獲取本類ip
      • Gets the host name for this IP address
    • java.net.InetAddress 類
      • 更多方法查詢api。

socket

  • 網路套接字,上面的瞭解,socket是實際程式設計中使用的類,會編寫基本的程式碼即可。
  • ServerSocket(int poart) //伺服器端(埠號)
  • Socket accept()//等待請求,阻塞狀態,返回套接字物件
  • Socket(String,poart) //客戶端,建立即連線
  • 127.0.0.1,代表本機,另外loacal也代表本機
  • 瀏覽器訪問Serversocket(),位址列輸入協議、ip、埠號即可
方法 功能
InetAddress getLocalAddress() 返回對方Socket中的IP的InetAddress物件
int getLocalPort() 返回本地Socket中的埠號
InetAddress getInetAddress() 返回對方Socket中IP地址
int getPort() 返回對方Socket中的埠號
void close() throws IOException 關閉Socket,不可在以後的網路連線中使用,除非建立新的套接字
InputStream getInputStream() throws IOException 獲取與Socket相關聯的位元組輸入流,用於從Socket中讀資料。
OutputStream getOutputStream() throws IOException 獲取與Socket相關聯的位元組輸出流,用於向Socket中寫資料。

ServerSocket類

方 法 功 能
Socket accept() throws IOException 等待客戶端的連線請求,返回與該客戶端進行通訊用的Socket物件
void setSoTimeout(int timeout) throws SocketException 設定accept()方法等待連線的時間為timeout毫秒。若時間已到,還沒有客戶端連線,則丟擲InterruptedIOException異常,accept()方法不再阻塞,該傾聽Socket可繼續使用。若timeout值為0,則表示accept()永遠等待。該方法必須在傾聽Socket建立後,在accept()之前呼叫才有效。
void close()throws IOException 關閉監聽Socket
InetAddress getInetAddress() 返回此伺服器套接字的本地地址
int getLocalPort() 返回此套接字在其上監聽的埠號
SocketAddress getLocalSocketAddress() 返回此套接字繫結的端點的地址

基於Socket的TCP程式設計

  • 客戶端Socket的工作過程包含以下四個基本的步驟:
    1. 建立 Socket:根據指定服務端的 IP 地址或埠號構造 Socket 類物件。若伺服器端響應,則建立客戶端到伺服器的通訊線路。若連線失敗,會出現異常。
    2. 開啟連線到 Socket 的輸入/出流: 使用 getInputStream()方法獲得輸入流,使用 getOutputStream()方法獲得輸出流,進行資料傳輸
    3. 按照一定的協議對 Socket 進行讀/寫操作:通過輸入流讀取伺服器放入線路的資訊(但不能讀取自己放入線路的資訊),通過輸出流將資訊寫入執行緒。
    4. 關閉 Socket:斷開客戶端到伺服器的連線,釋放線路
  • 客戶端
    • 客戶端程式可以使用Socket類建立物件,建立的同時會自動向伺服器方發起連線。Socket的構造方法是:
      • Socket(String host,int port)throws UnknownHostException,IOException:向伺服器(域名是host。埠號為port)發起TCP連線,若成功,則建立Socket物件,否則丟擲異常。
      • Socket(InetAddress address,int port)throws IOException:根據InetAddress物件所表示的IP地址以及埠號port發起連線。
    • 客戶端建立socketAtClient物件的過程就是向伺服器發出套接字連線請求
//客戶端模型
Socket s = new Socket(“192.168.40.165”,9999);
OutputStream out = s.getOutputStream();
out.write(“hello”.getBytes());
s.close();
  • 伺服器程式的工作過程包含以下四個基本的步驟:
    • 呼叫 ServerSocket(int port) :建立一個伺服器端套接字,並繫結到指定埠上。用於監聽客戶端的請求。
    • 呼叫 accept():監聽連線請求,如果客戶端請求連線,則接受連線,返回通訊套接字物件。
    • 呼叫 該Socket類物件的 getOutputStream() 和 getInputStream ():獲取輸出流和輸入流,開始網路資料的傳送和接收。
    • 關閉ServerSocket和Socket物件:客戶端訪問結束,關閉通訊套接字。
//伺服器模型
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept ();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = in.read(buf);
String str = new String(buf,0,num);
System.out.println(s.getInetAddress().toString()+”:”+str);
s.close();
ss.close();