服务端:
package cs;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
/**
* @author zzs
* @date 2021/9/22 20:49
*/
public class Server extends JFrame implements ActionListener, KeyListener {
//文本域
private JTextArea jta;
//滚动条
private JScrollPane jsp;
//面板
private JPanel jp;
//文本框
private JTextField jtf;
//按钮
private JButton jb;
//输出流
private BufferedWriter bw = null;
//服务端的端口号
private static int serverPort;
static {
Properties properties = new Properties();
try {
properties.load(new FileReader("chat.properties"));
//赋值
serverPort = Integer.parseInt(properties.getProperty("serverPort"));
} catch (IOException e) {
e.printStackTrace();
}
}
public Server() {
//初始化组件
jta = new JTextArea();
//文本域默认不可编辑
jta.setEnabled(false);
//将文本域添加到滚动条中实现滚动
jsp = new JScrollPane(jta);
jp = new JPanel();
jtf = new JTextField(20);
jb = new JButton("发送");
//将文本框和按钮添加到面板中
jp.add(jtf);
jp.add(jb);
//将滚动条和面板添加到窗体中
this.add(jsp, BorderLayout.CENTER);//放中间位置
this.add(jp,BorderLayout.SOUTH);//放于底部
//设置标题,大小,位置,关闭,可见
this.setTitle("服务端");
this.setSize(400,400);
this.setLocation(300,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭则退出
this.setVisible(true);
/*****************服务端开始*******************/
//给发送按钮绑定监听事件,需要继承ActionListener接口
jb.addActionListener(this);
//给文本框绑定一个回车键事件,KeyListener接口
jtf.addKeyListener(this);
try {
//1.创建Socket
ServerSocket serverSocket = new ServerSocket(serverPort);
//2.等待客户端连接
Socket socket = serverSocket.accept();
//3.获取输入流,读数据
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//4.获取输出流,写数据
OutputStream os = socket.getOutputStream();
bw = new BufferedWriter(new OutputStreamWriter(os));
//循环读取数据
String line = null;
while ((line = br.readLine())!=null){
//将读取到的数据置于文本域中
jta.append(line+System.lineSeparator());//内容后面接上换行
}
//5.关闭Socket通道
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
/*****************服务端结束*******************/
}
/**
* @Author zzs
* @Description //TODO 监听按钮事件
* @Date 21:49 2021/9/22
* @Param [e]
* @return void
**/
@Override
public void actionPerformed(ActionEvent e) {
sendData();
}
/**
* @Author zzs
* @Description //TODO 文本框回车键事件,3个方法,这里只需重写keyPressed方法
* @Date 22:30 2021/9/22
* @Param [e]
* @return void
**/
@Override
public void keyPressed(KeyEvent e) {
//回车键
if (e.getKeyCode()==KeyEvent.VK_ENTER){
//发送数据到socket通道中
sendData();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
public void sendData(){
//1.获取文本框中发送的内容
String text = jtf.getText();
//2.拼接发送的数据内容
text = "服务端: "+text;
//3.在服务端文本域中显示
jta.append(text+System.lineSeparator());
//4.发送数据
try {
bw.write(text);
bw.newLine();//换行
bw.flush();//刷新
//5.清空文本框内容
jtf.setText("");
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
new Server();
}
}
客户端:
package cs;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.Socket;
import java.util.Properties;
/**
* @author zzs
* @date 2021/9/22 20:49
*/
public class Client extends JFrame implements ActionListener, KeyListener {
//文本域
private JTextArea jta;
//滚动条
private JScrollPane jsp;
//面板
private JPanel jp;
//文本框
private JTextField jtf;
//按钮
private JButton jb;
//输出流
private BufferedWriter bw = null;
//客户端的ip , 端口号
private static String clientIP;
private static int clientPort;
static {
Properties properties = new Properties();
try {
properties.load(new FileReader("chat.properties"));
clientIP = properties.getProperty("clientIP");
clientPort = Integer.parseInt(properties.getProperty("clientPort"));
} catch (IOException e) {
e.printStackTrace();
}
}
public Client() {
//初始化组件
jta = new JTextArea();
//文本域默认不可编辑
jta.setEnabled(false);
//将文本域添加到滚动条中实现滚动
jsp = new JScrollPane(jta);
jp = new JPanel();
jtf = new JTextField(20);
jb = new JButton("发送");
//将文本框和按钮添加到面板中
jp.add(jtf);
jp.add(jb);
//将滚动条和面板添加到窗体中
this.add(jsp, BorderLayout.CENTER);//放中间位置
this.add(jp,BorderLayout.SOUTH);//放于底部
//设置标题,大小,位置,关闭,可见
this.setTitle("客户端");
this.setSize(400,400);
this.setLocation(700,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭则退出
this.setVisible(true);
/*****************客户端开始*******************/
//发送按钮绑定监听事件
jb.addActionListener(this);
//给文本框绑定回车键事件
jtf.addKeyListener(this);
try {
//1.创建Socket
Socket socket = new Socket(clientIP, clientPort);
//2.获取输入流,读数据
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//3.获取输出流,写数据
OutputStream os = socket.getOutputStream();
bw = new BufferedWriter(new OutputStreamWriter(os));
//循环读取数据
String line = null;
while ((line = br.readLine())!=null){
jta.append(line+System.lineSeparator());
}
//4.关闭Socket通道
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
/*****************客户端结束*******************/
}
/**
* @Author zzs
* @Description //TODO 客户端发送按钮监听事件
* @Date 22:02 2021/9/22
* @Param [e]
* @return void
**/
@Override
public void actionPerformed(ActionEvent e) {
sendData();
}
/**
* @Author zzs
* @Description //TODO 客户端给文本框绑定一个回车键事件
* @Date 22:39 2021/9/22
* @Param [e]
* @return void
**/
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER){
sendData();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
public void sendData(){
//1.获取文本框中发送的数据内容
String text = jtf.getText();
//2.拼接发送的内容
text = "客户端: "+ text;
//3.在客户端文本域中显示
jta.append(text+System.lineSeparator());
try {
//4.发送数据
bw.write(text);
//不换行和刷新,服务端会收不到信息
bw.newLine();
bw.flush();
//5.清空文本框
jtf.setText("");
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
new Client();
}
}
运行结果: