Java网络编程-简易聊天室源码分享
2022年6月8日更新,版本 v1.1
更新内容:
(1)应广大朋友要求,增加了滚动条
(2)同时修改了窗口的名称
(3)添加了一些注释
后续更新内容:考虑加一个群聊,目前好像是不行的,多开客户端会发生错误
代码放在下面了
同样需要先打开服务端,再打开客户端!
服务器端
1 import javax.swing.*; 2 import java.awt.event.ActionEvent; 3 import java.awt.event.ActionListener; 4 import java.awt.event.KeyAdapter; 5 import java.awt.event.KeyEvent; 6 import java.io.DataInputStream; 7 import java.io.DataOutputStream; 8 import java.io.IOException; 9 import java.net.ServerSocket; 10 import java.net.Socket; 11 import java.text.SimpleDateFormat; 12 import java.util.Date; 13 14 /** 15 * 服务器端窗口,先运行这个 16 */ 17 public class GUIServer { 18 19 public static void main(String[] args) { 20 // 创建窗体 21 JFrame f = new JFrame("JAVA版简易聊天室-服务器端"); 22 f.setLayout(null); 23 // 设置大小和位置 24 f.setSize(400, 300); 25 f.setLocation(100, 200); 26 // 发送按钮 27 JButton b = new JButton("发送"); 28 b.setBounds(290, 220, 80, 30); 29 f.add(b); 30 // 下侧聊天输入框 31 JTextField tf = new JTextField(); 32 tf.setBounds(10, 220, 260, 30); 33 f.add(tf); 34 // 上侧聊天内容 35 JTextArea ta = new JTextArea(); 36 // 设置为不可编辑 37 ta.setEditable(false); 38 // 文字比控件的宽度还长时会自动换行 39 ta.setLineWrap(true); 40 // 在单词边界换行,而不是粗暴的直接在字符边界换行 41 ta.setWrapStyleWord(true); 42 // 增加滚动条 43 JScrollPane sp = new JScrollPane(ta); 44 sp.setBounds(10, 10, 360, 200); 45 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 46 f.add(sp); 47 48 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 49 f.setVisible(true); 50 51 try { 52 // 设置服务器的端口为8888 53 ServerSocket ss = new ServerSocket(8888); 54 // 设置为接收模式 55 Socket s = ss.accept(); 56 // 发送按钮的点击事件 57 b.addActionListener(new ActionListener() { 58 @Override 59 public void actionPerformed(ActionEvent e) { 60 // 获取输入文本 61 String text = tf.getText(); 62 Date date = new Date(); 63 SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); 64 String now = sdf.format(date); 65 ta.append(now +"\r\n我:" + text + "\r\n"); 66 ta.setCaretPosition(ta.getText().length()); 67 // 设置输入框为空 68 tf.setText(""); 69 // 发送信息 70 try { 71 DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 72 dos.writeUTF(text); 73 } catch (IOException e1) { 74 e1.printStackTrace(); 75 } 76 } 77 }); 78 79 // 接收信息线程 80 new Thread() { 81 @Override 82 public void run() { 83 while (true) { 84 try { 85 // 获取其他用户的输入 86 DataInputStream dis = new DataInputStream(s.getInputStream()); 87 String text = dis.readUTF(); 88 String ip = s.getInetAddress().getHostAddress(); 89 Date date = new Date(); 90 SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); 91 String now = sdf.format(date); 92 // 添加到页面上 93 ta.append(now + "\r\n" + ip + ":" + text + "\r\n"); 94 ta.setCaretPosition(ta.getText().length()); 95 } catch (IOException e) { 96 e.printStackTrace(); 97 } 98 } 99 } 100 }.start(); 101 102 } catch (IOException e) { 103 e.printStackTrace(); 104 } 105 106 107 } 108 109 }
客户机端
import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; /** * 客户端程序 */ public class GUIClient { public static void main(String[] args) { // 创建窗体 JFrame f = new JFrame("JAVA版简易聊天室-客户机端"); f.setLayout(null); // 设置大小和位置 f.setSize(400, 300); f.setLocation(100, 200); // 发送按钮 JButton b = new JButton("发送"); b.setBounds(290, 220, 80, 30); f.add(b); // 下侧聊天输入框 JTextField tf = new JTextField(); tf.setBounds(10, 220, 260, 30); f.add(tf); // 上侧聊天内容 JTextArea ta = new JTextArea(); // 设置为不可编辑 ta.setEditable(false); // 文字比控件的宽度还长时会自动换行 ta.setLineWrap(true); // 在单词边界换行,而不是粗暴的直接在字符边界换行 ta.setWrapStyleWord(true); // 增加滚动条 JScrollPane sp = new JScrollPane(ta); sp.setBounds(10, 10, 360, 200); sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); f.add(sp); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.setVisible(true); try { // 设置连接服务器的地址为本机,端口为8888 Socket s = new Socket("127.0.0.1", 8888); b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 获取输入文本 String text = tf.getText(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); String now = sdf.format(date); ta.append(now +"\r\n我:" + text + "\r\n"); // 设置输入框为空 tf.setText(""); // 发送信息 try { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(text); } catch (IOException e1) { e1.printStackTrace(); } } }); // 接收信息线程 new Thread() { @Override public void run() { while (true) { try { // 获取其他用户的输入 DataInputStream dis = new DataInputStream(s.getInputStream()); String text = dis.readUTF(); String ip = s.getInetAddress().getHostAddress(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); String now = sdf.format(date); // 添加到页面上 ta.append(now + "\r\n" + ip + ":" + text + "\r\n"); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } catch (IOException e) { e.printStackTrace(); } } }
简易的聊天小程序,在使用时请先开启服务器程序,再运行客户端程序
package socket; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; /** * 服务器端窗口,先运行这个 */ public class GUIServer { public static void main(String[] args) { // 创建窗体 JFrame f = new JFrame("服务器"); f.setLayout(null); // 设置大小和位置 f.setSize(400, 300); f.setLocation(100, 200); JButton b = new JButton("发送"); b.setBounds(290, 220, 80, 30); f.add(b); JTextField tf = new JTextField(); tf.setBounds(10, 220, 260, 30); f.add(tf); JTextArea ta = new JTextArea(); ta.setBounds(10, 10, 360, 200); f.add(ta); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.setVisible(true); try { ServerSocket ss = new ServerSocket(8888); Socket s = ss.accept(); b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 获取输入文本 String text = tf.getText(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); String now = sdf.format(date); ta.append(now +"\r\n我:" + text + "\r\n"); ta.setCaretPosition(ta.getText().length()); // 设置输入框为空 tf.setText(""); // 发送信息 try { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(text); } catch (IOException e1) { e1.printStackTrace(); } } }); // 接收信息线程 new Thread() { @Override public void run() { while (true) { try { // 获取其他用户的输入 DataInputStream dis = new DataInputStream(s.getInputStream()); String text = dis.readUTF(); String ip = s.getInetAddress().getHostAddress(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); String now = sdf.format(date); // 添加到页面上 ta.append(now + "\r\n" + ip + ":" + text + "\r\n"); ta.setCaretPosition(ta.getText().length()); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } catch (IOException e) { e.printStackTrace(); } } }
package socket; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; /** * 客户端程序 */ public class GUIClient { public static void main(String[] args) { // 创建窗体 JFrame f = new JFrame("客户端"); f.setLayout(null); // 设置大小和位置 f.setSize(400, 300); f.setLocation(100, 200); JButton b = new JButton("发送"); b.setBounds(290, 220, 80, 30); f.add(b); JTextField tf = new JTextField(); tf.setBounds(10, 220, 260, 30); f.add(tf); JTextArea ta = new JTextArea(); ta.setBounds(10, 10, 360, 200); f.add(ta); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.setVisible(true); try { Socket s = new Socket("127.0.0.1", 8888); b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 获取输入文本 String text = tf.getText(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); String now = sdf.format(date); ta.append(now +"\r\n我:" + text + "\r\n"); // 设置输入框为空 tf.setText(""); // 发送信息 try { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(text); } catch (IOException e1) { e1.printStackTrace(); } } }); // 接收信息线程 new Thread() { @Override public void run() { while (true) { try { // 获取其他用户的输入 DataInputStream dis = new DataInputStream(s.getInputStream()); String text = dis.readUTF(); String ip = s.getInetAddress().getHostAddress(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); String now = sdf.format(date); // 添加到页面上 ta.append(now + "\r\n" + ip + ":" + text + "\r\n"); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } catch (IOException e) { e.printStackTrace(); } } }