MulticastSocketによるマルチキャスト(3)
4742 ワード
このUserInfoクラスのカプセル化により,すべてのクライアントがそのUserInfoクラスのリストを維持するだけで,プログラムはブロードキャスト,チャット情報の送信などの機能を実現できる.このプログラムの下位レベルで通信するツールクラスには、次のようなコードを持つMulticastSocketとDatagramSocketが必要です.
プログラムリスト:codes/17/17-4/LanTalk/ComUtil.java
プログラムリスト: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);
}
}
}
}
}