import java.io.*;
import java.net.*;
import java.util.Vector;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class ChipChat extends JFrame
{
JPanel contentPane;
JTextField txtInput = new JTextField();
JButton btnSend = new JButton();
JButton TCPconnect = new JButton();
List lstMsg = new List();
List lstFriend = new List();
JLabel name = new JLabel();
JLabel Top = new JLabel();
JLabel version = new JLabel();
UserInfo [] userinfo = new UserInfo[90];//新建UserInfo数组类保存用户信息
ServerSocket listen_socket;
public final static int DEFAULT_PORT = 8321;
public final static int CATCH_PORT = 7321;
public final static int TCP_PORT = 6321;
DatagramSocket socket = null;
InetAddress group;
InetAddress groupC;
DatagramPacket packet;
DatagramSocket s = null;
MulticastSocket socketr;
MulticastSocket socketC;
Socket Csocket;
CCListener cclisten;
String nickname = new String("11111111111");
public ChipChat()//构造函数
{
while(nickname.length()>9||nickname.length()==0)
{
nickname = JOptionPane.showInputDialog(null,"请输入昵称","登陆",3);
if(nickname.length()>9)
JOptionPane.showMessageDialog(null,"昵称长度需要小于10","非法昵称",JOptionPane.ERROR_MESSAGE);
if(nickname.length()==0)
JOptionPane.showMessageDialog(null,"昵称长度需要等于0","非法昵称",JOptionPane.ERROR_MESSAGE);
}
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
ChipChat_JoinGroup();//首先初始化端口,并向已经在线的CC程序发送本机IP以及请求回应.并对相应的组播组端口进行监听
try
{
jbInit();//初始化FRAME窗口,并对相应的控件添加事件响应
}catch(Exception e)
{
e.printStackTrace();
}
this.setLocation(300,200);
ChipChat_Listener();//对组内公共聊天的组播组端口进行监听
TCP_Listener();//对点对点TCP协议端口进行监听
}
protected void processWindowEvent(WindowEvent e)
{
super.processWindowEvent(e);
if(e.getID()==WindowEvent.WINDOW_CLOSING)
{
try
{
//退出时发送退出登陆的信息的组播数据包,其包的内容的起始位为判断位,"D"表示该包为告知下线的信息包
byte [] notice = new String("D"+nickname+InetAddress.getLocalHost().getHostAddress()+nickname.length()).getBytes();
packet = new DatagramPacket(notice,notice.length,groupC,CATCH_PORT);
socket.send(packet);
}catch(IOException ee)
{
ee.printStackTrace();
}
socket.close();
System.exit(0);
}
}
public void jbInit()//初始化应用程序窗口
{
version.setText("V1.2");
version.setBounds(new Rectangle(420,5,50,30));
txtInput.setText("");
txtInput.setBounds(new Rectangle(80,140,140,30));
txtInput.addKeyListener(new KeyAdapter (){//添加事件按键事件监听,当文本框中按下"回车"时则发送文本框消息
public void keyPressed(KeyEvent ek){
if(ek.getKeyChar() == '\n')
try {
byte[] dataS = (nickname+":"+txtInput.getText()).getBytes();
packet = new DatagramPacket(dataS,dataS.length, group, DEFAULT_PORT);
socket.send(packet);
txtInput.setText("");
}
catch(Exception e1)
{
System.out.println("Error: " + e1);
}
}
});
contentPane = (JPanel)this.getContentPane();
contentPane.setLayout(null);
name = new JLabel(nickname+":");
name.setBounds(new Rectangle(20,140,50,30));
this.setSize(480,210);
this.setTitle("ChipChat");
Icon sentIcon = new ImageIcon("image\\BTSend.gif");
Icon BG = new ImageIcon("image\\BackGround1.gif");
Icon TCPIcon = new ImageIcon("image\\BTConnect.gif");
Top.setIcon(BG);
Top.setBounds(0,0,480,183);
btnSend.setIcon(sentIcon);
btnSend.setBounds(230,141,89,32);
btnSend.setBackground(Color.WHITE);
btnSend.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
btnSend_actionPerformed(e);
}
});
TCPconnect.setIcon(TCPIcon);
TCPconnect.setBounds(new Rectangle(355,140,89,32));
TCPconnect.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
TCPconnect_actionPerformed(e);
}
});
lstMsg.setBounds(new Rectangle(20,35,300,100));
lstFriend.setBounds(new Rectangle(340,35,120,100));
lstFriend.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
lstFriend_actionPerformed(e);
}
});
contentPane.add(txtInput,null);
contentPane.add(btnSend,null);
contentPane.add(lstMsg,null);
contentPane.add(name,null);
contentPane.add(version,null);
contentPane.add(lstFriend,null);
contentPane.add(TCPconnect,null);
contentPane.setBackground(Color.WHITE);
contentPane.add(Top,null);
this.setResizable(false);
}
public static void main(String [] arg)//主函数,程序入口
{
ChipChat cc = new ChipChat();
cc.setVisible(true);
}
public void processMsg(String str)//该方法为将字符串str显示到对话列表框中
{
this.lstMsg.add(str);
this.lstMsg.select(lstMsg.getItemCount()-1);
}
public void processFriend(String str)//该方法为将字符串str显示到登陆信息列表框中
{
this.lstFriend.add(str);
}
public void ChipChat_JoinGroup()//初始化UDP协议端口信息
{
try {
group = InetAddress.getByName("238.0.0.0"); //初始化广播聊天信息组播组
groupC = InetAddress.getByName("239.0.0.0");//初始化登陆信息组播组
socket = new DatagramSocket();
byte [] notify = new byte[100];
byte [] nametag = new byte[10];
nametag = nickname.getBytes();
//发送一个登陆信息给已经登陆的用户,通知他们本程序上线.包的数据结构为:判断位+用户名+IP地址+用户名长度
notify =new String("C"+nickname+InetAddress.getLocalHost().getHostAddress()+nickname.length()).getBytes();
//int dd = InetAddress.getLocalHost().getHostAddress().length();
packet = new DatagramPacket(notify,notify.length,groupC,CATCH_PORT);
socket.send(packet);
socketC = new MulticastSocket(CATCH_PORT);
socketC.joinGroup(groupC);
CATCHER catcher = new CATCHER(socketC,this,nickname,userinfo);
Check_in LOGIN = new Check_in(this,userinfo);
}
catch (Exception e1) {
System.out.println("Error: " + e1);
}
}
void lstFriend_actionPerformed(ActionEvent e)//双击登陆列表框内容时触发的事件为连通列表框中的IP,建立TCP通信
{
Socket socket;
int s = this.lstFriend.getSelectedIndex();
String address = userinfo[s].getIP();//用address记录对方IP地址
try
{
socket = new Socket(address,TCP_PORT);//建立连接
TCP_Frame TT = new TCP_Frame(socket,userinfo[s].getName());//打开TCP会话程序
TT.setVisible(true);
}catch(IOException elf)
{
elf.printStackTrace();
}
}
void TCPconnect_actionPerformed(ActionEvent e)//连接按钮事件监听
{
Socket socketT;
String NN = null;
int s = this.lstFriend.getSelectedIndex();
try
{
NN = userinfo[s].getName();
}catch(Exception nu)
{
JOptionPane.showMessageDialog(null,"请从按钮上方选择想要连接的地址","空目标地址",JOptionPane.ERROR_MESSAGE);
}
try
{
//对所选择的登陆信息列表框中的内容建立TCP连接
String address = userinfo[s].getIP();//this.lstFriend.getSelectedItem().substring(2);
socketT = new Socket(address,TCP_PORT);
TCP_Frame TT = new TCP_Frame(socketT,userinfo[s].getName());
TT.setVisible(true);
}catch(IOException es)
{
JOptionPane.showMessageDialog(null,"该用户已不在线","用户下线",JOptionPane.ERROR_MESSAGE);
try
{
byte [] notice = new String("D"+NN+InetAddress.getLocalHost().getHostAddress()+NN.length()).getBytes();
packet = new DatagramPacket(notice,notice.length,groupC,CATCH_PORT);
socket.send(packet);
}catch(IOException
评论0