欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java Socket編程筆記_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

 更新時(shí)間:2017年05月27日 11:01:17   投稿:mrr  
Socket對(duì)于我們來(lái)說(shuō)就非常實(shí)用了。下面是本次學(xué)習(xí)的筆記。主要分異常類(lèi)型、交互原理、Socket、ServerSocket、多線(xiàn)程這幾個(gè)方面闡述

對(duì)于即時(shí)類(lèi)應(yīng)用或者即時(shí)類(lèi)的游戲,HTTP協(xié)議很多時(shí)候無(wú)法滿(mǎn)足于我們的需求。這會(huì),Socket對(duì)于我們來(lái)說(shuō)就非常實(shí)用了。下面是本次學(xué)習(xí)的筆記。主要分異常類(lèi)型、交互原理、Socket、ServerSocket、多線(xiàn)程這幾個(gè)方面闡述。

異常類(lèi)型

在了解Socket的內(nèi)容之前,先要了解一下涉及到的一些異常類(lèi)型。以下四種類(lèi)型都是繼承于IOException,所以很多之后直接彈出IOException即可。

UnkownHostException:      主機(jī)名字或IP錯(cuò)誤
ConnectException:        服務(wù)器拒絕連接、服務(wù)器沒(méi)有啟動(dòng)、(超出隊(duì)列數(shù),拒絕連接)
SocketTimeoutException:      連接超時(shí)
BindException:          Socket對(duì)象無(wú)法與制定的本地IP地址或端口綁定 

交互過(guò)程

Socket與ServerSocket的交互,下面的圖片我覺(jué)得已經(jīng)說(shuō)的很詳細(xì)很清楚了。 

Socket構(gòu)造函數(shù)

Socket()
Socket(InetAddress address, int port)throws UnknownHostException, IOException
Socket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException
Socket(String host, int port)throws UnknownHostException, IOException
Socket(String host, int port, InetAddress localAddress, int localPort)throws IOException

除去第一種不帶參數(shù)的之外,其它構(gòu)造函數(shù)會(huì)嘗試建立與服務(wù)器的連接。如果失敗會(huì)拋出IOException錯(cuò)誤。如果成功,則返回Socket對(duì)象。

InetAddress是一個(gè)用于記錄主機(jī)的類(lèi),其靜態(tài)getHostByName(String msg)可以返回一個(gè)實(shí)例,其靜態(tài)方法getLocalHost()也可以獲得當(dāng)前主機(jī)的IP地址,并返回一個(gè)實(shí)例。Socket(String host, int port, InetAddress localAddress, int localPort)構(gòu)造函數(shù)的參數(shù)分別為目標(biāo)IP、目標(biāo)端口、綁定本地IP、綁定本地端口。 

Socket方法

getInetAddress();      遠(yuǎn)程服務(wù)端的IP地址
getPort();          遠(yuǎn)程服務(wù)端的端口
getLocalAddress()      本地客戶(hù)端的IP地址
getLocalPort()        本地客戶(hù)端的端口
getInputStream();     獲得輸入流
getOutStream();      獲得輸出流

值得注意的是,在這些方法里面,最重要的就是getInputStream()和getOutputStream()了。 

Socket狀態(tài)

isClosed();            //連接是否已關(guān)閉,若關(guān)閉,返回true;否則返回false
isConnect();      //如果曾經(jīng)連接過(guò),返回true;否則返回false
isBound();            //如果Socket已經(jīng)與本地一個(gè)端口綁定,返回true;否則返回false

如果要確認(rèn)Socket的狀態(tài)是否處于連接中,下面語(yǔ)句是很好的判斷方式。

boolean isConnection=socket.isConnected() && !socket.isClosed();   //判斷當(dāng)前是否處于連接

半關(guān)閉Socket

很多時(shí)候,我們并不知道在獲得的輸入流里面到底讀多長(zhǎng)才結(jié)束。下面是一些比較普遍的方法:

  •  自定義標(biāo)識(shí)符(譬如下面的例子,當(dāng)受到“bye”字符串的時(shí)候,關(guān)閉Socket)
  •  告知讀取長(zhǎng)度(有些自定義協(xié)議的,固定前幾個(gè)字節(jié)表示讀取的長(zhǎng)度的)
  •  讀完所有數(shù)據(jù)
  •  當(dāng)Socket調(diào)用close的時(shí)候關(guān)閉的時(shí)候,關(guān)閉其輸入輸出流 

ServerSocket構(gòu)造函數(shù)

ServerSocket()throws IOException
ServerSocket(int port)throws IOException
ServerSocket(int port, int backlog)throws IOException
ServerSocket(int port, int backlog, InetAddress bindAddr)throws IOException 

注意點(diǎn):

1. port服務(wù)端要監(jiān)聽(tīng)的端口;backlog客戶(hù)端連接請(qǐng)求的隊(duì)列長(zhǎng)度;bindAddr服務(wù)端綁定IP

2. 如果端口被占用或者沒(méi)有權(quán)限使用某些端口會(huì)拋出BindException錯(cuò)誤。譬如1~1023的端口需要管理員才擁有權(quán)限綁定。

3. 如果設(shè)置端口為0,則系統(tǒng)會(huì)自動(dòng)為其分配一個(gè)端口;

4. bindAddr用于綁定服務(wù)器IP,為什么會(huì)有這樣的設(shè)置呢,譬如有些機(jī)器有多個(gè)網(wǎng)卡。

5. ServerSocket一旦綁定了監(jiān)聽(tīng)端口,就無(wú)法更改。ServerSocket()可以實(shí)現(xiàn)在綁定端口前設(shè)置其他的參數(shù)。 

單線(xiàn)程的ServerSocket例子 

public void service(){
  while(true){
    Socket socket=null;
    try{
      socket=serverSocket.accept();//從連接隊(duì)列中取出一個(gè)連接,如果沒(méi)有則等待
      System.out.println("新增連接:"+socket.getInetAddress()+":"+socket.getPort());
      ...//接收和發(fā)送數(shù)據(jù)
    }catch(IOException e){e.printStackTrace();}finally{
      try{
        if(socket!=null) socket.close();//與一個(gè)客戶(hù)端通信結(jié)束后,要關(guān)閉Socket
      }catch(IOException e){e.printStackTrace();}
    }
  }
}

多線(xiàn)程的ServerSocket

多線(xiàn)程的好處不用多說(shuō),而且大多數(shù)的場(chǎng)景都是多線(xiàn)程的,無(wú)論是我們的即時(shí)類(lèi)游戲還是IM,多線(xiàn)程的需求都是必須的。下面說(shuō)說(shuō)實(shí)現(xiàn)方式:

  •  主線(xiàn)程會(huì)循環(huán)執(zhí)行ServerSocket.accept();
  •  當(dāng)拿到客戶(hù)端連接請(qǐng)求的時(shí)候,就會(huì)將Socket對(duì)象傳遞給多線(xiàn)程,讓多線(xiàn)程去執(zhí)行具體的操作;

實(shí)現(xiàn)多線(xiàn)程的方法要么繼承Thread類(lèi),要么實(shí)現(xiàn)Runnable接口。當(dāng)然也可以使用線(xiàn)程池,但實(shí)現(xiàn)的本質(zhì)都是差不多的。

這里舉例:

下面代碼為服務(wù)器的主線(xiàn)程。為每個(gè)客戶(hù)分配一個(gè)工作線(xiàn)程:

public void service(){
  while(true){
    Socket socket=null;
    try{
      socket=serverSocket.accept();            //主線(xiàn)程獲取客戶(hù)端連接
      Thread workThread=new Thread(new Handler(socket));  //創(chuàng)建線(xiàn)程
      workThread.start();                  //啟動(dòng)線(xiàn)程
    }catch(Exception e){
      e.printStackTrace();
    }
  }
}

當(dāng)然這里的重點(diǎn)在于如何實(shí)現(xiàn)Handler這個(gè)類(lèi)。Handler需要實(shí)現(xiàn)Runnable接口: 

class Handler implements Runnable{
  private Socket socket;
  public Handler(Socket socket){
    this.socket=socket;
  }
  
  public void run(){
    try{
      System.out.println("新連接:"+socket.getInetAddress()+":"+socket.getPort());
      Thread.sleep(10000);
    }catch(Exception e){e.printStackTrace();}finally{
      try{
        System.out.println("關(guān)閉連接:"+socket.getInetAddress()+":"+socket.getPort());
        if(socket!=null)socket.close();
      }catch(IOException e){
        e.printStackTrace();
      }
    }
  }
}

當(dāng)然是先多線(xiàn)程還有其它的方式,譬如線(xiàn)程池,或者JVM自帶的線(xiàn)程池都可以。這里就不說(shuō)明了。

以上所述是小編給大家介紹的Java Socket編程筆記_,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Java泛型 <T> T、 T、<T>的用法小結(jié)

    Java泛型 <T> T、 T、<T>的用法小結(jié)

    T在Java泛型中,被稱(chēng)作類(lèi)型變量, 有的方法返回值是<T> T,有的是T,區(qū)別在哪里,本文主要介紹了Java泛型 <T> T、 T、<T>的用法小結(jié),具有一定的參考價(jià)值,感興趣的可以了解下
    2023-12-12
  • Spring之從橋接方法到JVM方法調(diào)用解讀

    Spring之從橋接方法到JVM方法調(diào)用解讀

    這篇文章主要介紹了Spring之從橋接方法到JVM方法調(diào)用解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Spring中的路徑匹配器AntPathMatcher詳解

    Spring中的路徑匹配器AntPathMatcher詳解

    這篇文章主要介紹了Spring中的路徑匹配器AntPathMatcher詳解,Spring的PathMatcher路徑匹配器接口,用于支持帶通配符的資源路徑匹配,本文提供了部分實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2023-09-09
  • 解決問(wèn)題:Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources

    解決問(wèn)題:Failed to execute goal org.apache.m

    這篇文章主要給大家介紹了關(guān)于解決問(wèn)題:Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources的相關(guān)資料,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • SpringBoot開(kāi)發(fā)實(shí)戰(zhàn)系列之定時(shí)器

    SpringBoot開(kāi)發(fā)實(shí)戰(zhàn)系列之定時(shí)器

    定時(shí)任務(wù)我想諸位童鞋都不陌生,簡(jiǎn)而言之名為“設(shè)定定時(shí)鬧鐘做某件事情”,下面這篇文章主要給大家介紹了關(guān)于SpringBoot定時(shí)器的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Redisson可重入鎖解鎖邏輯詳細(xì)講解

    Redisson可重入鎖解鎖邏輯詳細(xì)講解

    Redisson開(kāi)源框架是一個(gè)Redis的分布式鎖的現(xiàn)成實(shí)現(xiàn)方案,是Redis的java實(shí)現(xiàn)的客戶(hù)端。通過(guò)Netty支持非阻塞I/O。Redisson實(shí)現(xiàn)了分布式鎖的自動(dòng)續(xù)期機(jī)制、鎖的互斥自等待機(jī)制、鎖的可重入加鎖與釋放鎖的機(jī)制
    2023-02-02
  • SpringBoot整合Spring?Boot?Admin實(shí)現(xiàn)服務(wù)監(jiān)控的方法

    SpringBoot整合Spring?Boot?Admin實(shí)現(xiàn)服務(wù)監(jiān)控的方法

    這篇文章主要介紹了SpringBoot整合Spring?Boot?Admin實(shí)現(xiàn)服務(wù)監(jiān)控,內(nèi)容包括Server端服務(wù)開(kāi)發(fā),Client端服務(wù)開(kāi)發(fā)其中Spring Boot Admin還可以對(duì)其監(jiān)控的服務(wù)提供告警功能,如服務(wù)宕機(jī)時(shí),可以及時(shí)以郵件方式通知運(yùn)維人員,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • Java使用枚舉替代if/else和switch-case語(yǔ)句的實(shí)踐

    Java使用枚舉替代if/else和switch-case語(yǔ)句的實(shí)踐

    在軟件開(kāi)發(fā)中if-else和switch-case語(yǔ)句經(jīng)常被用來(lái)處理不同的條件分支,但在大型項(xiàng)目中,這種做法可能導(dǎo)致代碼可讀性差、維護(hù)困難,這篇文章主要給大家介紹了關(guān)于Java使用枚舉替代if/else和switch-case語(yǔ)句的相關(guān)資料,需要的朋友可以參考下
    2024-09-09
  • 新手初學(xué)Java網(wǎng)絡(luò)編程

    新手初學(xué)Java網(wǎng)絡(luò)編程

    網(wǎng)絡(luò)編程是指編寫(xiě)運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過(guò)網(wǎng)絡(luò)連接起來(lái)。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來(lái)實(shí)現(xiàn)TCP和UDP的Socket的編程,來(lái)讓讀者更好的了解其原理
    2021-07-07
  • Java 泛型詳解與范例

    Java 泛型詳解與范例

    hello !大家好!今天的主題就是:泛型。在使用集合類(lèi)時(shí),大家就已經(jīng)接觸到泛型了,那就是每個(gè)集合類(lèi)后面的尖括號(hào)<>,這樣一對(duì)尖括號(hào),在java中就稱(chēng)為泛型。那么泛型這一個(gè)點(diǎn),我們又該知道多少呢?我們往下看
    2021-11-11

最新評(píng)論