开发思路:
服务端两个Socket:
客户端一个Socket:
生疏知识点:
图形化界面按钮监控键盘
addActionListener(AbstractAction接口实现类);监听器。
**topTextField.getInputMap().put(KeyStroke.getKeyStroke('\n'),"confirm_username"); 键盘事件和名字关联;
**
topTextField.getActionMap().put("confirm_username",confirmListener); 事件别名和监听器关联
服务器端程序:
package tcpandudp.udpexample;
import java.io.IOException;
import java.net.*;
/**
* @ClassName MulticastServerScoket
* @projectName: object1
* @author: Zhangmingda
* @description: 设计思想:为避免所有人直接发广播,导致消息内容无环节把控,消息发送的时候,发送到非广播端口(作为一个服务端)再由此服务端向广播地址发送消息,
* date: 2021/5/13.
*/
public class MulticastServerScoket {
/**
* 广播Socket端口
*/
private static final int BROAD_PORT = 30000;
/**
* 广播IP地址 :224.0.0.0 到 239.255.255.255
*/
private static final String BROAD_IP = "230.3.3.3";
/**
* 服务端口
*/
private static final int SERVER_PORT = 8888;
private void start(){
try (
/**
* 广播用套接字
*/
MulticastSocket multicastSocket = new MulticastSocket(BROAD_PORT);
/**
* 服务端套接字
*/
DatagramSocket datagramSocket = new DatagramSocket(SERVER_PORT)
){
/**
* 广播IP地址
*/
InetAddress multi_addr = InetAddress.getByName(BROAD_IP);
/**
* 广播套接字配置接收广播的IP地址
*/
multicastSocket.joinGroup(multi_addr);
/**
* 构建接收UDP数据的包
*/
byte[] inBuff = new byte[4096];
DatagramPacket inPacket = new DatagramPacket(inBuff,inBuff.length);
/**
* 接收广播,并广播出去
*/
while (true){
//普通套接字收广播
datagramSocket.receive(inPacket);
String content = new String(inPacket.getData(),0,inPacket.getLength());
System.out.println(content);
//广播套接字发广播
DatagramPacket outPacket = new DatagramPacket(inPacket.getData(),inPacket.getLength(),multi\_addr,BROAD\_PORT);
multicastSocket.send(outPacket);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/\*\*
\* 程序入口
\*/
public static void main(String\[\] args) {
new MulticastServerScoket().start();
}
}
客户端
package tcpandudp.udpexample;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;
/**
* @ClassName MulticastClientSocket
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/13.
*/
public class MulticastClientSocket {
/**
* 广播Socket端口
*/
private static final int BROAD_PORT = 30000;
/**
* 广播IP地址 :224.0.0.0 到 239.255.255.255
*/
private static final String BROAD_IP = "230.3.3.3";
/\*\*
\* 要发送数据包的服务端IP地址和 端口
\*/
private static final String SERVER\_IP = "127.0.0.1";
private static final int SERVER\_PORT = 8888;
private void go() {
JFrame jFrame = new JFrame("广播聊天客户端");
//上部
JPanel topPanel = new JPanel();
JTextField topTextField = new JTextField(30);
JButton topButton = new JButton("确认用户名");
topPanel.add(topTextField);
topPanel.add(topButton);
jFrame.add(topPanel, BorderLayout.NORTH);
//中部
JTextArea centerArea = new JTextArea(10,40);
JScrollPane centerPane = new JScrollPane(centerArea);
jFrame.add(centerPane);
//下
JPanel bottomPanel = new JPanel();
JTextField bottomTextField = new JTextField(35);
JButton sendButton = new JButton("发送");
bottomPanel.add(bottomTextField);
bottomPanel.add(sendButton);
jFrame.add(bottomPanel, BorderLayout.SOUTH);
jFrame.setLocation(400,300);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT\_ON\_CLOSE);
jFrame.pack();
jFrame.setVisible(true);
AtomicReference<String> username = new AtomicReference<>("");
//确认用户名事件监听器
Action confirmListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
String topTextContent = topTextField.getText();
if (topTextContent != null && ! "".equals(topTextContent)){
username.set(topTextContent);
System.out.println("用户名设置成功");
}
}
};
//绑定事件监听器
topButton.addActionListener(confirmListener);
topTextField.getInputMap().put(KeyStroke.getKeyStroke('\\n'),"confirm\_username");
topTextField.getActionMap().put("confirm\_username",confirmListener);
/\*\*
\* 发送&接收用socket
\*/
try{
MulticastSocket mClinetSocket = new MulticastSocket(BROAD\_PORT);
InetAddress multi\_addr = InetAddress.getByName(BROAD\_IP);
/\*\*
\* 接收端
\*/
new Thread(){
@Override
public void run() {
byte\[\] inBuff = new byte\[4096\];
/\*\*
\* 构建接收包
\*/
DatagramPacket inPacket = new DatagramPacket(inBuff,0,inBuff.length);
while (true){
/\*\*
\* 接收数据放包里,转为字符串打印出来
\*/
try {
mClinetSocket.receive(inPacket);
} catch (IOException e) {
e.printStackTrace();
}
String content = new String(inPacket.getData(),0, inPacket.getLength());
System.out.println(content);
centerArea.append(content + "\\n"); //向文本框加入文本
}
}
}.start();
/\*\*
\* 套接字加入广播地址
\*/
mClinetSocket.joinGroup(multi\_addr);
/\*\*
\* 服务端地址构建
\*/
InetAddress server\_addr = InetAddress.getByName(SERVER\_IP);
/\*\*
\* 构建发出包
\*/
DatagramPacket outPacket = new DatagramPacket(new byte\[0\],0,server\_addr,SERVER\_PORT);
/\*\*
\* 发送按钮监听器
\*/
Action sendListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (username.get().equals("")){
System.err.println("请输入用户名");
}else {
String sendContent = bottomTextField.getText();
if (sendContent != null && ! "".equals(sendContent)){
sendContent = username + ":" + sendContent;
//输入字节存入包,
outPacket.setData(sendContent.getBytes());
try {
mClinetSocket.send(outPacket);
bottomTextField.setText(null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
};
/\*\*
\* 发送按钮绑定监听器
\*/
sendButton.addActionListener(sendListener);
//内容框监听键盘
bottomTextField.getInputMap().put(KeyStroke.getKeyStroke('\\n'),"send");
bottomTextField.getActionMap().put("send",sendListener);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String\[\] args) {
new MulticastClientSocket().go();
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章