运行结果:
注:服务器主要是为了转发客户端代码,可以将服务器的窗口代码去除,客户端名字在运行时获取用户输入的名称来命名
客户端代码:
package roomV2;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientFrame extends JFrame {
Socket socket;
String name;
public ClientFrame() {
//运行客户端时获取输入的名称并将窗口命名
name = JOptionPane.showInputDialog("请输入名字:");
setTitle(name);
setLayout(null);
setBounds(100, 100, 500, 500);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JTextArea jTextArea = new JTextArea();
jTextArea.setBounds(20, 20, 420, 300);
JScrollPane sPane =new JScrollPane();
sPane.setBounds(20, 20, 420, 300);
sPane.setViewportView(jTextArea);
JTextField jTextField = new JTextField();
jTextField.setBounds(20, 340, 330, 50);
JButton send = new JButton("发送");
send.setBounds(350, 340, 100, 50);
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//发送消息给服务器
try {
OutputStream out = socket.getOutputStream();
String sendMsg = jTextField.getText();
if(sendMsg!="") {
DataOutputStream dataOutputStream = new DataOutputStream(out);
dataOutputStream.writeUTF(sendMsg);
}else {
System.out.println("不能发送空消息");
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
jTextField.setText("");
}
});
add(send);
add(jTextField);
add(sPane);
setVisible(true);
connectServer();
ReciveMsgForClient client = new ReciveMsgForClient(jTextArea, socket);
client.start();
}
/**
* 连接服务器
*/
public void connectServer() {
try {
socket = new Socket("127.0.0.1", 8888);
//TODO 把名字发送到服务器
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
dataOutputStream.writeUTF(name);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
ClientFrame clientFrame = new ClientFrame();
}
}
class ReciveMsgForClient extends Thread {
JTextArea jTextArea;
Socket socket;
public ReciveMsgForClient(JTextArea jTextArea,Socket socket) {
this.jTextArea = jTextArea;
this.socket = socket;
}
@Override
public void run() {
while(true) {
String msg = reciveMsg();
jTextArea.setText(jTextArea.getText()+"\n"+msg);
}
}
/**
* 接收消息
*/
public String reciveMsg() {
String msg = "";
try {
InputStream in = socket.getInputStream();
DataInputStream inputStream = new DataInputStream(in);
msg = inputStream.readUTF();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return msg;
}
}
服务器端代码:
package roomV2;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class SeverFrame extends JFrame{
//List<Socket> sockets = new ArrayList<Socket>();
public static Map<String,Socket> clients=new HashMap<>();
Socket socket;
JTextArea jTextArea;
static String name;
JTextField jTextField;
public SeverFrame() {
setTitle("服务器");
setLayout(null);
setBounds(100, 100, 500, 500);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
jTextArea = new JTextArea();
jTextArea.setBounds(20, 20, 420, 300);
JScrollPane sPane =new JScrollPane();
sPane.setBounds(20, 20, 420, 300);
sPane.setViewportView(jTextArea);
jTextField = new JTextField();
jTextField.setBounds(20, 340, 330, 50);
JButton send = new JButton("发送");
send.setBounds(350, 340, 100, 50);
add(send);
add(jTextField);
add(sPane);
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String sendMsg = jTextField.getText();
sendMsg(sendMsg);
jTextField.setText("");
}
});
setVisible(true);
startServer();
}
/**
* 广播文本框消息给所有客户端
*/
public void sendMsg(String msg) {
需要向客户端发送信息
//遍历map
for(String a:clients.keySet()){
try {
OutputStream outputStream = clients.get(a).getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 开启服务器,等待连接
*/
public void startServer() {
try {
ServerSocket socketServer = new ServerSocket(8888);
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
socket = socketServer.accept();
//接收客户端登录时传入的名字 TODO
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream=new DataInputStream(inputStream);
name = dataInputStream.readUTF();
//使用map name 为key socket为value
clients.put(name,socket);
InetAddress address = socket.getInetAddress();
ReciveMsg reciveMsg = new ReciveMsg(jTextArea,socket,clients);
reciveMsg.start();
System.out.println("客户端连接成功"+address.getHostAddress());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
//启动窗口
SeverFrame severFrame = new SeverFrame();
}
}
class ReciveMsg extends Thread {
JTextArea jTextArea;
Socket socket;
static Map<String,Socket> maps;
public ReciveMsg(JTextArea jTextArea,Socket socket,Map<String,Socket> maps) {
this.jTextArea = jTextArea;
this.socket = socket;
this.maps=maps;
}
@Override
public void run() {
while(true) {
String msg = reciveMsg();
if(msg != null) {
jTextArea.setText(jTextArea.getText()+"\n"+msg);
}
}
}
/**
* 接收消息
*/
public String reciveMsg() {
String msg = null;
try {
if(socket != null) {
InputStream in = socket.getInputStream();
DataInputStream inputStream = new DataInputStream(in);
msg = inputStream.readUTF();
sendMsg(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
/**
* 广播消息给所有客户端
*/
public void sendMsg(String msg) {
需要向客户端发送信息
String name="";
for(String a:maps.keySet()) {
if(socket==maps.get(a)) {
name=a;
}
}
//遍历map
for(String a:maps.keySet()){
try {
OutputStream outputStream = maps.get(a).getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF(name+"说:"+msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}