一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - [Java]詳解Socket和ServerSocket學習筆記

[Java]詳解Socket和ServerSocket學習筆記

2020-07-15 11:57Ron Ngai Java教程

即時類應用或者即時類的游戲,HTTP協議很多時候無法滿足于我們的需求,這會,Socket對于我們來說就非常實用了。本篇文章主要介紹了Socket和ServerSocket,有興趣的可以了解一下。

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

異常類型

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

UnkownHostException:   主機名字或IP錯誤

ConnectException:  服務器拒絕連接、服務器沒有啟動、(超出隊列數,拒絕連接)

SocketTimeoutException: 連接超時

BindException:  Socket對象無法與制定的本地IP地址或端口綁定

交互過程

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

[Java]詳解Socket和ServerSocket學習筆記

Socket

構造函數

?
1
2
3
4
5
6
7
8
9
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

除去第一種不帶參數的之外,其它構造函數會嘗試建立與服務器的連接。如果失敗會拋出IOException錯誤。如果成功,則返回Socket對象。

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

Socket方法

getInetAddress();      遠程服務端的IP地址

getPort();          遠程服務端的端口

getLocalAddress()      本地客戶端的IP地址

getLocalPort()        本地客戶端的端口

getInputStream();     獲得輸入流

getOutStream();      獲得輸出流

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

Socket狀態

isClosed();            //連接是否已關閉,若關閉,返回true;否則返回false

isConnect();      //如果曾經連接過,返回true;否則返回false

isBound();            //如果Socket已經與本地一個端口綁定,返回true;否則返回false

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

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

半關閉Socket

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

  • 自定義標識符(譬如下面的例子,當受到“bye”字符串的時候,關閉Socket)
  • 告知讀取長度(有些自定義協議的,固定前幾個字節表示讀取的長度的)
  • 讀完所有數據
  • 當Socket調用close的時候關閉的時候,關閉其輸入輸出流

ServerSocket

構造函數

?
1
2
3
4
5
6
7
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服務端要監聽的端口;backlog客戶端連接請求的隊列長度;bindAddr服務端綁定IP

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

3. 如果設置端口為0,則系統會自動為其分配一個端口;

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

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

 單線程的ServerSocket例子

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void service(){
  while(true){
    Socket socket=null;
    try{
      socket=serverSocket.accept();//從連接隊列中取出一個連接,如果沒有則等待
      System.out.println("新增連接:"+socket.getInetAddress()+":"+socket.getPort());
      ...//接收和發送數據
    }catch(IOException e){e.printStackTrace();}finally{
      try{
        if(socket!=null) socket.close();//與一個客戶端通信結束后,要關閉Socket
      }catch(IOException e){e.printStackTrace();}
    }
  }
}

多線程的ServerSocket

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

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

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

 這里舉例:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
public void service(){
  while(true){
    Socket socket=null;
    try{
      socket=serverSocket.accept();            //主線程獲取客戶端連接
      Thread workThread=new Thread(new Handler(socket));  //創建線程
      workThread.start();                  //啟動線程
    }catch(Exception e){
      e.printStackTrace();
    }
  }
}

 當然這里的重點在于如何實現Handler這個類。Handler需要實現Runnable接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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("關閉連接:"+socket.getInetAddress()+":"+socket.getPort());
        if(socket!=null)socket.close();
      }catch(IOException e){
        e.printStackTrace();
      }
    }
  }
}

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/rond/p/3565113.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: videojapan日本孕交孕 | 俄罗斯12一15处交 | 欧美第十页 | ccc在线在线36 | 无人在线高清免费看 | 亚洲欧美日韩特级毛片 | 亚洲精品午夜在线观看 | 五月色婷婷在线影院 | japonensis中国东北老人 | 大好硬好深好爽想要视频 | 亚洲精品国产精品麻豆99 | 亚洲一区二区三区福利在线 | 67194在线免费观看 | 免费观看视频高清在线 | 大胸被c出奶水嗷嗷叫 | 国产成人精选免费视频 | 欧美精品久久久久久久免费观看 | 乳 好大h | 色综合久久九月婷婷色综合 | 国产午夜永久福利视频在线观看 | 日本无遮挡亲吻膜下面免费 | 精品国产欧美一区二区 | 蜜桃久久久亚洲精品成人 | 亚洲第一男人天堂 | 禁忌第一季第3季 | 末代皇帝无删减版在线观看 | 国产精品九九热 | 天天狠天天透天干天天怕处 | 男人午夜视频在线观看 | 精品视频在线免费观看 | 亚洲视频在线观看免费 | eeuss18影院www国产 | 久久成人伊人欧洲精品AV | 四虎1515hh.com| 青青国产在线观看 | 91入口免费网站大全 | 爽好舒服宝贝添奶吻戏 | 青青青青久久国产片免费精品 | 九九热在线视频观看这里只有精品 | 暗卫调教女主肉高h | 免费看男女做好爽好硬视频 |