MulticastSocketによるマルチキャスト(3)

4742 ワード

このUserInfoクラスのカプセル化により,すべてのクライアントがそのUserInfoクラスのリストを維持するだけで,プログラムはブロードキャスト,チャット情報の送信などの機能を実現できる.このプログラムの下位レベルで通信するツールクラスには、次のようなコードを持つMulticastSocketとDatagramSocketが必要です.
プログラムリスト:codes/17/17-4/LanTalk/ComUtil.java
//          
public class ComUtil
{
//              IP  
private static final String BROADCAST_IP
= "230.0.0.1";
//                   
//DatagramSocket          -1。
public static final int BROADCAST_PORT = 30000;
//             4K
private static final int DATA_LEN = 4096;
//      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 , inBuff.length);
//         DatagramPacket  
private DatagramPacket outPacket = null; 
//      
private LanChat lanTalk;
//   ,     
public ComUtil(LanChat lanTalk)throws IOException , InterruptedException
{
this.lanTalk = lanTalk;
//      、     MulticastSocket  
//   MulticastSocket      ,       
socket = new MulticastSocket(BROADCAST_PORT);
//      DatagramSocket  
singleSocket = new DatagramSocket(BROADCAST_PORT + 1);
broadcastAddress = InetAddress.getByName(BROADCAST_IP);
//  socket           
socket.joinGroup(broadcastAddress);
//   MulticastSocket            
socket.setLoopbackMode(false);
//       DatagramSocket,        0     
outPacket = new DatagramPacket(new byte[0] , 0 ,
broadcastAddress , BROADCAST_PORT);
//             
new ReadBroad().start();
Thread.sleep(1);
new ReadSingle().start();
}
//         
public void broadCast(String msg)
{
try
{
// msg         
byte[] buff = msg.getBytes();
//      DatagramPacket      
outPacket.setData(buff);
//     
socket.send(outPacket);
}
//    
catch (IOException ex)
{
ex.printStackTrace();
if (socket != null)
{
//   Socket  
socket.close();
}
JOptionPane.showMessageDialog(null, 
"      ,   30000    ,       !"
, "    ", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
//              
public void sendSingle(String msg , SocketAddress dest)
{
try
{
// msg         
byte[] buff = msg.getBytes();
DatagramPacket packet = new DatagramPacket(
buff , buff.length , dest);
singleSocket.send(packet);
}
//    
catch (IOException ex)
{
ex.printStackTrace();
if (singleSocket != null)
{
//   Socket  
singleSocket.close();
}
JOptionPane.showMessageDialog(null, 
"      ,   30001    ,       !"
, "    ", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
//   DatagramSocket        
class ReadSingle extends Thread
{
//             
byte[] singleBuff = new byte[DATA_LEN];
private DatagramPacket singlePacket = 
new DatagramPacket(singleBuff , singleBuff.length);
public void run()
{
while (true)
{
try
{
//  Socket    ,       inPacket         。
singleSocket.receive(singlePacket);
//       
lanTalk.processMsg(singlePacket , true);
}
//    
catch (IOException ex)
{
ex.printStackTrace();
if (singleSocket != null)
{
//   Socket  
singleSocket.close();
}
JOptionPane.showMessageDialog(null,
"      ,   30001    ,       !"
, "    ", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
}
}
//    MulticastSocket   
class ReadBroad extends Thread
{
public void run()
{
while (true)
{
try
{
//  Socket    ,       inPacket         。
socket.receive(inPacket);
//     socket      
String msg = new String(inBuff , 0 , inPacket.getLength());
//          
if (msg.startsWith(YeekuProtocol.PRESENCE)
&& msg.endsWith(YeekuProtocol.PRESENCE))
{
String userMsg = msg.substring(2 , msg.length() - 2);
String[] userInfo = userMsg.split(YeekuProtocol.SPLITTER);
UserInfo user = new UserInfo(userInfo[1] , userInfo[0] , 
inPacket.getSocketAddress(), 0);
//              
boolean addFlag = true;
ArrayList<Integer> delList = new ArrayList<Integer>();
//            ,         
for (int i = 1 ; i < lanTalk.getUserNum() ; i++ )
{
UserInfo current = lanTalk.getUser(i);
//             1
current.setLost(current.getLost() + 1);
//              
if (current.equals(user))
{
current.setLost(0);
//         
addFlag = false;
}
if (current.getLost() > 2)
{
delList.add(i);
}
}
//  delList           
for (int i = 0; i < delList.size() ; i++)
{
lanTalk.removeUser(delList.get(i));
}
if (addFlag)
{
//     
lanTalk.addUser(user);
}
}
//          
else
{
//       
lanTalk.processMsg(inPacket , false);
}
}
//    
catch (IOException ex)
{
ex.printStackTrace();
if (socket != null)
{
//   Socket  
socket.close();
}
JOptionPane.showMessageDialog(null,
"      ,   30000    ,       !"
, "    ", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
}
}
}