局域网聊天室需要完成以下几个功能:
* 1.局域网中各主机都能参与到聊天室中聊天,即可以接发消息,其中接受可以接受每台主机发送的消息,发送的消息每台主机都能收到
* 2.简陋界面
实现思想:
1.先实现界面的设计。创建自己的J711ChatRoom()类来继承JFrame()类。即可随意编写界面。
2.发送消息采用多播数据通道MulticastSocket,并且利用joinGroup()方法给其指定一个多播地址groupIp。每个主机都用DatagramPacket来打包自己的消息,然后将数据包发送到多播地址,改数据包得从指定的端口发送,然后MulticastSocket就可以调用send方法把主机发送的数据包给广播出去。
3.接收消息采用线程来实现,因为接受消息是实时进行的,所以要实现接受的同时还能发送消息,则可以利用线程的阻塞来完成。首先在指定端口中开启多播通道MulticastSocket,然后利用joinGroup()方法给其指定一个多播地址groupIp。然后利用receive()方法从多播通道中获取数据包。此处获取数据包的代码处于死循环状态,使其保持一直接受消息的状态。然后将接受到的消息append到文本域中。
一些细节:
setLayout(null); // 设置布局方式,为null则代表控件可以根据自身设置的位置任意摆放
setLocationRelativeTo(null); // 参数为null此窗口置于屏幕的中央
ms.joinGroup(“/226.81.9.8");// 地址前要加一个反斜杠
以下是运行效果:
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.border.LineBorder;
public class J711ChatRoom extends JFrame{
public static void main(String[] args) {
new J711ChatRoom();
}
private JLabel label1;
private JTextArea area1;// 文本域
private JTextArea area2;// 文本域
private JButton button;
private Insets margin = new Insets(10, 10, 10, 10); // 让发出去的消息与边框隔开10个单位
public J711ChatRoom(){
setTitle("聊天室");
setSize(500, 500);
setLocationRelativeTo(null); // 参数为null此窗口置于屏幕的中央
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
// 设置布局方式,为null则代表控件可以根据自身设置的位置任意摆放
setLayout(null);
initUI();
setVisible(true);
}
private void initUI() {
label1 = createJLabel("J711聊天室", 180, 20, 200, 30);
area1 = createJTextArea(50, 60, 395, 230);
area1.setMargin(margin);// 前面空两格
area2 = createJTextArea(50, 300, 395, 100);
button = new JButton("发送");
button.setBounds(345, 410, 100, 30);
new Receiver().start();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Send(area2.getText());
area2.setText("");
}
});
add(label1);
add(area1);
add(area2);
add(button);
}
/**************发送消息***************/
public void Send(String msg){
try {
//创建多播数据报通道 (发数据) DatagramPacket
MulticastSocket ms = new MulticastSocket();
//客户端要接到消息都必须通过下面这个地址
InetAddress groupIp = InetAddress.getByName("226.81.9.8");
ms.joinGroup(groupIp);//将socket通道加入多播地址
//将需要发送的数据打包为数据报包
String content = msg;//广播内容
//数据包
DatagramPacket dp = new DatagramPacket(content.getBytes(), content.getBytes().length);
//先把消息发到多播地址
dp.setAddress(groupIp);
dp.setPort(2426);
//发送包裹
ms.send(dp);
} catch (IOException e) {
e.printStackTrace();
}
}
/*************接收消息**************/
public class Receiver extends Thread{
@Override
public void run() {
try {
int count = 0;
//占据指定的端口开启多播通道
MulticastSocket ms = new MulticastSocket(2426);
InetAddress groupIp = InetAddress.getByName("226.81.9.8");
ms.joinGroup(groupIp);
String s = "";
Date date = null;
SimpleDateFormat sdf;
byte[] b = new byte[1024];
//声明数据报包,用于接收广播信息
DatagramPacket dp = new DatagramPacket(b, b.length);
while(true){
count++;
if (count % 8 == 0) area1.setText("");
date = new Date();// 获取当前时间即消息发送的时间
sdf = new SimpleDateFormat("HH:mm:ss");
dp = new DatagramPacket(b, b.length);
ms.receive(dp);
s = new String(dp.getData(), dp.getOffset(), dp.getLength());
s = dp.getAddress() + " "+ sdf.format(date) + "\n" + s + "\n";
area1.append(s);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public JTextArea createJTextArea(int x, int y, int w, int h){
JTextArea area = new JTextArea();
area.setBounds(x, y, w, h);
area.setLineWrap(true); // 自动换行
area.setBorder(new LineBorder(new Color(129, 152, 48)));
return area;
}
public JLabel createJLabel(String name, int x, int y, int w, int h){
JLabel label = new JLabel(name);
//设置控件的边界 x y 宽 高
label.setBounds(x, y, w, h);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setFont(new Font("楷体", Font.BOLD, 20));
label.setForeground(Color.RED);
return label;
}
}