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

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

2022-06-13   來源: Java核心技術 

  通過該UserInfo類的封裝這樣所有客戶端只需要維護該UserInfo類的列表程序就可以實現廣播發送私聊信息等功能本程序底層通信的工具類則需要一個MulticastSocket和一個DatagramSocket該工具類的代碼如下

  程序清單codes///LanTalk/ComUtiljava

  //聊天交換信息的工具類

  public class ComUtil

  {

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

  private static final String BROADCAST_IP

  = ;

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

  //DatagramSocket所用的的端口為該端口

  public static final int BROADCAST_PORT = ;

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

  private static final int DATA_LEN = ;

  //定義本程序的MulticastSocket實例

  private MulticastSocket socket = null;

  //定義本程序私聊的Socket實例

  private DatagramSocket singleSocket = null;

  //定義廣播的IP地址

  private InetAddress broadcastAddress = null;

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

  byte[] inBuff = new byte[DATA_LEN];

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

  private DatagramPacket inPacket =

  new DatagramPacket(inBuff inBufflength)

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

  private DatagramPacket outPacket = null;

  //聊天的主界面

  private LanChat lanTalk;

  //構造器初始化資源

  public ComUtil(LanChat lanTalk)throws IOException InterruptedException

  {

  thislanTalk = lanTalk;

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

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

  socket = new MulticastSocket(BROADCAST_PORT)

  //創建私聊用的DatagramSocket對象

  singleSocket = new DatagramSocket(BROADCAST_PORT +

  broadcastAddress = InetAddressgetByName(BROADCAST_IP)

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

  socketjoinGroup(broadcastAddress)

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

  socketsetLoopbackMode(false)

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

  outPacket = new DatagramPacket(new byte[]

  broadcastAddress BROADCAST_PORT)

  //啟動兩個讀取網絡數據的線程

  new ReadBroad()start()

  Threadsleep(

  new ReadSingle()start()

  }

  //廣播消息的工具方法

  public void broadCast(String msg)

  {

  try

  {

  //將msg字符串轉換字節數組

  byte[] buff = msggetBytes()

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

  outPacketsetData(buff)

  //發送數據報

  socketsend(outPacket)

  }

  //捕捉異常

  catch (IOException ex)

  {

  exprintStackTrace()

  if (socket != null)

  {

  //關閉該Socket對象

  socketclose()

  }

  JOptionPaneshowMessageDialog(null

  發送信息異常請確認端口空閒且網絡連接正常!

   網絡異常 JOptionPaneERROR_MESSAGE)

  Systemexit(

  }

  }

  //定義向單獨用戶發送消息的方法

  public void sendSingle(String msg SocketAddress dest)

  {

  try

  {

  //將msg字符串轉換字節數組

  byte[] buff = msggetBytes()

  DatagramPacket packet = new DatagramPacket(

  buff bufflength dest)

  singleSocketsend(packet)

  }

  //捕捉異常

  catch (IOException ex)

  {

  exprintStackTrace()

  if (singleSocket != null)

  {

  //關閉該Socket對象

  singleSocketclose()

  }

  JOptionPaneshowMessageDialog(null

  發送信息異常請確認端口空閒且網絡連接正常!

   網絡異常 JOptionPaneERROR_MESSAGE)

  Systemexit(

  }

  }

  //不斷從DatagramSocket中讀取數據的線程

  class ReadSingle extends Thread

  {

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

  byte[] singleBuff = new byte[DATA_LEN];

  private DatagramPacket singlePacket =

  new DatagramPacket(singleBuff singleBufflength)

  public void run()

  {

  while (true)

  {

  try

  {

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

  singleSocketreceive(singlePacket)

  //處理讀到的信息

  lanTalkprocessMsg(singlePacket true)

  }

  //捕捉異常

  catch (IOException ex)

  {

  exprintStackTrace()

  if (singleSocket != null)

  {

  //關閉該Socket對象

  singleSocketclose()

  }

  JOptionPaneshowMessageDialog(null

  接收信息異常請確認端口空閒且網絡連接正常!

   網絡異常 JOptionPaneERROR_MESSAGE)

  Systemexit(

  }

  }

  }

  }

  //持續讀取MulticastSocket的線程

  class ReadBroad extends Thread

  {

  public void run()

  {

  while (true)

  {

  try

  {

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

  socketreceive(inPacket)

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

  String msg = new String(inBuff inPacketgetLength())

  //讀到的內容是在線信息

  if (msgstartsWith(YeekuProtocolPRESENCE)

  && msgendsWith(YeekuProtocolPRESENCE))

  {

  String userMsg = msgsubstring( msglength()

  String[] userInfo = userMsgsplit(YeekuProtocolSPLITTER)

  UserInfo user = new UserInfo(userInfo[] userInfo[]

  inPacketgetSocketAddress()

  //控制是否需要添加該用戶的旗標

  boolean addFlag = true;

  ArrayList<Integer> delList = new ArrayList<Integer>()

  //遍歷系統中已有的所有用戶該循環必須循環完成

  for (int i = ; i < lanTalkgetUserNum() ; i++ )

  {

  UserInfo current = lanTalkgetUser(i)

  //將所有用戶失去聯系的次數加

  currentsetLost(currentgetLost() +

  //如果該信息由指定用戶發送過來

  if (currentequals(user))

  {

  currentsetLost(

  //設置該用戶無須添加

  addFlag = false;

  }

  if (currentgetLost() >

  {

  delListadd(i)

  }

  }

  //刪除delList中的所有索引對應的用戶

  for (int i = ; i < delListsize() ; i++)

  {

  lanTalkremoveUser(delListget(i))

  }

  if (addFlag)

  {

  //添加新用戶

  lanTalkaddUser(user)

  }

  }

  //讀到的內容是公聊信息

  else

  {

  //處理讀到的信息

  lanTalkprocessMsg(inPacket false)

  }

  }

  //捕捉異常

  catch (IOException ex)

  {

  exprintStackTrace()

  if (socket != null)

  {

  //關閉該Socket對象

  socketclose()

  }

  JOptionPaneshowMessageDialog(null

  接收信息異常請確認端口空閒且網絡連接正常!

   網絡異常 JOptionPaneERROR_MESSAGE)

  Systemexit(

  }

  }

  }

  }

  }

       返回目錄瘋狂Java講義

       編輯推薦

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

       新手學Java 編程

       Java程序設計培訓視頻教程


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