熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

瘋狂Java講義:使用MulticastSocket實現多點廣播(1)

2013-11-23 19:39:17  來源: Java核心技術 

   使用MulticastSocket實現多點廣播

  DatagramSocket只允許數據報發送給指定的目標地址而MulticastSocket可以將數據報以廣播方式發送到數量不等的多個客戶端

  若要使用多點廣播時則需要讓一個數據報標有一組目標主機地址當數據報發出後整個組的所有主機都能收到該數據報IP多點廣播(或多點發送)實現了將單一信息發送到多個接收者的廣播其思想是設置一組特殊網絡地址作為多點廣播地址每一個多點廣播地址都被看做一個組當客戶端需要發送接收廣播信息時加入到該組即可

  IP協議為多點廣播提供了這批特殊的IP地址這些IP地址的范圍是 多點廣播的示意圖如圖所示

多點廣播的示意圖

  從圖中可以看出通過Java實現多點廣播時MulticastSocket類是實現這一功能的關鍵當MulticastSocket把一個DatagramPacket發送到多點廣播IP地址該數據報將被自動廣播到加入該地址的所有MulticastSocketMulticastSocket類既可以將數據報發送到多點廣播地址也可以接收其他主機的廣播信息

  MulticastSocket有點像DatagramSocket事實上MulticastSocket是DatagramSocket的一個子類也就是說MulticastSocket是特殊的DatagramSocket若要發送一個數據報時可使用隨機端口創建MulticastSocket也可以在指定端口來創建MulticastSocket

  MulticastSocket提供了如下三個構造器

  public MulticastSocket()使用本機默認地址隨機端口來創建一個MulticastSocket對象

  public MulticastSocket(int portNumber)使用本機默認地址指定端口來創建一個MulticastSocket對象

  public MulticastSocket(SocketAddress bindaddr)使用本機指定IP地址指定端口來創建一個MulticastSocket對象

  創建一個MulticastSocket對象後還需要將該MulticastSocket加入到指定的多點廣播地址MulticastSocket使用jionGroup()方法來加入指定組使用leaveGroup()方法脫離一個組

  joinGroup(InetAddress multicastAddr)將該MulticastSocket加入指定的多點廣播地址

  leaveGroup(InetAddress multicastAddr)讓該MulticastSocket離開指定的多點廣播地址

  在某些系統中可能有多個網絡接口這可能會對多點廣播帶來問題這時候程序需要在一個指定的網絡接口上監聽通過調用setInterface可選擇MulticastSocket所使用的網絡接口也可以使用getInterface方法查詢MulticastSocket監聽的網絡接口

  如果創建僅用於發送數據報的MulticastSocket對象則使用默認地址隨機端口即可但如果創建接收用的MulticastSocket對象則該MulticastSocket對象必須具有指定端口否則發送方無法確定發送數據報的目標端口

  MulticastSocket用於發送接收數據報的方法與DatagramSocket的完全一樣但MulticastSocket比DatagramSocket多一個setTimeToLive(int ttl)方法該ttl參數設置數據報最多可以跨過多少個網絡當ttl為指定數據報應停留在本地主機當ttl的值為指定數據報發送到本地局域網當ttl的值為意味著只能發送到本站點的網絡上當ttl為意味著數據報應保留在本地區當ttl的值為意味著數據報應保留在本大洲當ttl為意味著數據報可發送到所有地方默認情況下該ttl的值為

  從圖中可以看出使用MulticastSocket進行多點廣播時所有通信實體都是平等的它們都將自己的數據報發送到多點廣播IP地址並使用MulticastSocket接收其他人發送的廣播數據報下面程序使用MulticastSocket實現了一個基於廣播的多人聊天室程序只需要一個MulticastSocket兩條線程其中MulticastSocket既用於發送也用於接收其中一條線程分別負責接受用戶鍵盤輸入並向MulticastSocket發送數據另一條線程則負責從MulticastSocket中讀取數據

  程序清單codes///MulticastSocketTestjava

  //讓該類實現Runnable接口該類的實例可作為線程的target

  public class MulticastSocketTest implements Runnable

  {

  //使用常量作為本程序的多點廣播IP地址

  private static final String BROADCAST_IP

  = ;

  //使用常量作為本程序的多點廣播目的的端口

  public static final int BROADCAST_PORT = ;

  //定義每個數據報的最大大小為K

  private static final int DATA_LEN = ;

  //定義本程序的MulticastSocket實例

  private MulticastSocket socket = null;

  private InetAddress broadcastAddress = null;

  private Scanner scan = null;

  //定義接收網絡數據的字節數組

  byte[] inBuff = new byte[DATA_LEN];

  //以指定字節數組創建准備接受數據的DatagramPacket對象

  private DatagramPacket inPacket =

  new DatagramPacket(inBuff inBufflength)

  //定義一個用於發送的DatagramPacket對象

  private DatagramPacket outPacket = null;

  public void init()throws IOException

  {

  try

  {

  //創建用於發送接收數據的MulticastSocket對象

  //因為該MulticastSocket對象需要接收所以有指定端口

  socket = new MulticastSocket(BROADCAST_PORT)

  broadcastAddress = InetAddressgetByName(BROADCAST_IP)

  //將該socket加入指定的多點廣播地址

  socketjoinGroup(broadcastAddress)

  //設置本MulticastSocket發送的數據報被回送到自身

  socketsetLoopbackMode(false)

  //初始化發送用的DatagramSocket它包含一個長度為的字節數組

  outPacket = new DatagramPacket(new byte[]

  broadcastAddress BROADCAST_PORT)

  //啟動以本實例的run()方法作為線程體的線程

  new Thread(this)start()

  //創建鍵盤輸入流

  scan = new Scanner(Systemin)

  //不斷讀取鍵盤輸入

  while(scanhasNextLine())

  {

  //將鍵盤輸入的一行字符串轉換字節數組

  byte[] buff = scannextLine()getBytes()

  //設置發送用的DatagramPacket裡的字節數據

  outPacketsetData(buff)

  //發送數據報

  socketsend(outPacket)

  }

  }

  finally

  {

  socketclose()

  }

  }

  public void run()

  {

  try

  {

  while(true)

  {

  //讀取Socket中的數據讀到的數據放在inPacket所封裝的字節數組裡

  socketreceive(inPacket)

  //打印輸出從socket中讀取的內容

  Systemoutprintln(聊天信息 + new String(inBuff

  inPacketgetLength()))

  }

  }

  //捕捉異常

  catch (IOException ex)

  {

  exprintStackTrace()

  try

  {

  if (socket != null)

  {

  //讓該Socket離開該多點IP廣播地址

  socketleaveGroup(broadcastAddress)

  //關閉該Socket對象

  socketclose()

  }

  Systemexit(

  }

  catch (IOException e)

  {

  eprintStackTrace()

  }

  }

  }

  public static void main(String[] args)

  throws IOException

  {

  new MulticastSocketTest()init()

  }

  }

  上面程序中init()方法裡的前三行粗體字代碼先創建了一個MulticastSocket對象由於需要使用該對象接收數據報所以為該Socket對象設置使用固定端口第二行粗體字代碼將該Socket對象添加到指定的多點廣播IP地址第三行粗體字代碼設置該Socket發送的數據報會被回送到自身(即該Socket可以接受到自己發送的數據報)至於程序中使用MulticastSocket發送接收數據報的代碼與使用DatagramSocket並沒有區別故此處不再贅述

       返回目錄瘋狂Java講義

       編輯推薦

       Java程序性能優化讓你的Java程序更快更穩定

       新手學Java 編程

       Java程序設計培訓視頻教程


From:http://tw.wingwit.com/Article/program/Java/hx/201311/27258.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.