📄 catcher.java
字号:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
/*
* 线程类CATCHER,该类实现对登陆信息端口的监听,以及识别各类与登陆相关的数据包的类别的识别.
* 并在收到要求应答的数据包的时候发送一个包含请求端用户名以及本机IP的数据包到组播组,此数
* 据包由所有在线的终端接受,但只有用户名与包中包含用户名相同的终端对其予以显示,以此方法来
* 实现对后来登陆的终端告知已经在线的用户.
* 当请求应答的终端用户名与本程序用户重名时作出必要判断,实现不在本机显示重复的登陆信息.
*/
class CATCHER extends Thread
{
MulticastSocket Csocket;
Socket CheckSocket;
ChipChat server;
InetAddress Cgroup ;
DatagramPacket packet;
DatagramSocket socket;
String tag;
int i = 0,k;
BufferedReader in;
PrintWriter out;
UserInfo [] userinfo;
public final static int CATCH_PORT = 7321;
public final static int CHECK_PORT = 5000;
public CATCHER(MulticastSocket socketin,ChipChat CC,String name,UserInfo [] ui)//构造函数
{
//接受由上层函数传来的参数
Csocket = socketin;
server = CC;
tag = name;
userinfo = ui;
try
{
Cgroup = InetAddress.getByName("239.0.0.0");
}catch(Exception e){}
this.start();
}
public void run()//run()实现对组播端口的监听,并作出反映
{
try
{
socket = new DatagramSocket();
while (true) {
byte[] Rdata = new byte[256];
packet = new DatagramPacket(Rdata, Rdata.length);
Csocket.receive(packet);//等待接受数据包
//count记录了数据包的最后一位数,也就是记录了用户名的长度.
String count = new String(packet.getData()).substring(packet.getLength()-1,packet.getLength());
int num = Integer.parseInt(count);//num为int类型,记录了用户名的长度.
//根据数据包的数据结构,check记录了从1+num开始的到倒数第二位的字符.就是数据包中包含的IP地址.
String check = new String(packet.getData()).substring(1+num, packet.getLength()-1);
String judge = new String(packet.getData()).substring(0,1);
//根据数据包的数据结构,usertag记录了从第二位到num+1长度的信息,也就是用户名
String usertag = new String(packet.getData()).substring(1,num+1);
// judge为"C"时反送一个含有对方用户名以及本机IP的数据包到组播组
if(judge.equals("C"))
{
i = server.lstFriend.getItemCount();
processMsg(usertag);
userinfo[i] = new UserInfo(usertag,check);
Ring();
Connect(check);
}
// judge为"D"时删除登陆信息框中的终端的IP地址
if(judge.equals("D"))
{
while(userinfo[i] != null)
{
String l = userinfo[i].getName();
if(l.equals(usertag))
{
k=i;
while(userinfo[k] != null)
{
userinfo[k] = userinfo[k+1];
k ++;
}
break;
}
}
try{
removeMsg(usertag);
}
catch(Exception n)
{
try
{
removeMsg(usertag);
}catch(Exception n2){}
}
}
}
}catch(Exception er)
{
er.printStackTrace();
}
}
/*
* Connect()方法实现了对对方回应本机信息的过程,其中第一以及最后一个为无用的信息,在接收方被吸收掉
*/
public void Connect(String check)
{
try
{
CheckSocket = new Socket(check,CHECK_PORT);
in = new BufferedReader(new InputStreamReader(CheckSocket.getInputStream()));
out = new PrintWriter(CheckSocket.getOutputStream());
out.println("-------------------------------------");
out.flush();
out.println(tag);
out.flush();
out.println(InetAddress.getLocalHost().getHostAddress());
out.flush();
out.println("---");
out.flush();
}catch(Exception t)
{
try
{
in.close();
out.close();
CheckSocket.close();
}catch(IOException l)
{
l.printStackTrace();
}
t.printStackTrace();
}
finally
{
try
{
in.close();
out.close();
CheckSocket.close();
}catch(IOException m)
{
m.printStackTrace();
}
}
}
public void Ring()
{
FileInputStream file;
try {
file=new FileInputStream("sound\\BELL.wav");
AudioStream as=new AudioStream(file);
AudioPlayer.player.start(as);
}
catch (Exception e) {}
}
public void processMsg(String str)//在应用程序的登陆信息框中显示信息
{
server.lstFriend.add(str);
}
public void removeMsg(String str)//在应用程序的登陆信息框中删去信息
{
server.lstFriend.remove(str);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -