最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Socket編程筆記_動力節(jié)點Java學(xué)院整理

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

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

異常類型

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

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

交互過程

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

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ù)會嘗試建立與服務(wù)器的連接。如果失敗會拋出IOException錯誤。如果成功,則返回Socket對象。

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

Socket方法

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

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

Socket狀態(tài)

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

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

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

半關(guān)閉Socket

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

  •  自定義標識符(譬如下面的例子,當受到“bye”字符串的時候,關(guān)閉Socket)
  •  告知讀取長度(有些自定義協(xié)議的,固定前幾個字節(jié)表示讀取的長度的)
  •  讀完所有數(shù)據(jù)
  •  當Socket調(diào)用close的時候關(guān)閉的時候,關(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 

注意點:

1. port服務(wù)端要監(jiān)聽的端口;backlog客戶端連接請求的隊列長度;bindAddr服務(wù)端綁定IP

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

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

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

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

單線程的ServerSocket例子 

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

多線程的ServerSocket

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

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

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

這里舉例:

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

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

當然這里的重點在于如何實現(xiàn)Handler這個類。Handler需要實現(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();
      }
    }
  }
}

當然是先多線程還有其它的方式,譬如線程池,或者JVM自帶的線程池都可以。這里就不說明了。

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

相關(guān)文章

  • java jdk動態(tài)代理詳解

    java jdk動態(tài)代理詳解

    動態(tài)代理類的Class實例是怎么生成的呢,是通過ProxyGenerator類來生成動態(tài)代理類的class字節(jié)流,把它載入方法區(qū)
    2013-09-09
  • Java中的@Accessors使用詳解

    Java中的@Accessors使用詳解

    這篇文章主要介紹了Java中的@Accessors使用詳解,@RequiredArgsConstructor是Lombok的一個注解,簡化了我們對setter和getter方法操作,它可以作用在類上,也可以作用在類的單個屬性上,需要的朋友可以參考下
    2024-01-01
  • Java?Optional的判空操作詳解

    Java?Optional的判空操作詳解

    JAVA在1.8版本推出Optional,官方文檔將其描述為可能包含或不包含非空值的容器對象,目前Optional用于避免程序出現(xiàn)異常NullPointerException,感興趣的可以了解一下
    2022-09-09
  • SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解

    SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解

    這篇文章主要介紹了SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解,ApplicationListener是應(yīng)用程序的事件監(jiān)聽器,繼承自java.util.EventListener標準接口,采用觀察者設(shè)計模式,需要的朋友可以參考下
    2023-11-11
  • RestTemplate請求失敗自動重啟機制精講

    RestTemplate請求失敗自動重啟機制精講

    這篇文章主要為大家介紹了RestTemplate請求失敗自定義處理的方法,自動重試的機制精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多所進步,早日升職加薪
    2022-03-03
  • java如何實時動態(tài)獲取properties文件的內(nèi)容

    java如何實時動態(tài)獲取properties文件的內(nèi)容

    這篇文章主要介紹了java如何實時動態(tài)獲取properties文件的內(nèi)容,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • intellij idea中spring boot properties文件不能自動提示問題解決

    intellij idea中spring boot properties文件不能自動提示問題解決

    這篇文章主要介紹了intellij idea中spring boot properties文件不能自動提示問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • JPA原生SQL實現(xiàn)增刪改查的示例詳解

    JPA原生SQL實現(xiàn)增刪改查的示例詳解

    JPA除了對JPQL提供支持外,還對原生SQL語句也提供了支持。本文將利用生SQL實現(xiàn)增刪改查功能,文中的示例代碼講解詳細,需要的可以參考一下
    2022-09-09
  • SpringBoot2 整合 ClickHouse數(shù)據(jù)庫案例解析

    SpringBoot2 整合 ClickHouse數(shù)據(jù)庫案例解析

    這篇文章主要介紹了SpringBoot2 整合 ClickHouse數(shù)據(jù)庫案例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • springboot+quartz以持久化的方式實現(xiàn)定時任務(wù)的代碼

    springboot+quartz以持久化的方式實現(xiàn)定時任務(wù)的代碼

    這篇文章主要介紹了springboot+quartz以持久化的方式實現(xiàn)定時任務(wù)的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07

最新評論

正安县| 会东县| 土默特右旗| 汉沽区| 通辽市| 麻江县| 邓州市| 福海县| 大竹县| 连州市| 盘锦市| 大荔县| 阿鲁科尔沁旗| 射阳县| 万荣县| 胶南市| 旅游| 通化市| 石楼县| 武宣县| 旬阳县| 班戈县| 正阳县| 嵊州市| 通许县| 靖西县| 吉木乃县| 灵宝市| 聂拉木县| 扎赉特旗| 汪清县| 吉木萨尔县| 双城市| 江川县| 安吉县| 雷山县| 汝阳县| 延吉市| 太谷县| 林口县| 伽师县|