当前位置:   article > 正文

用Java实现简易聊天室_java聊天室代码

java聊天室代码

 

说明:如果一个 类,需要有界面的显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个“窗体类"。

 

服务端代码:

  1. package cn.qy.chat;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.KeyEvent;
  7. import java.awt.event.KeyListener;
  8. import java.io.*;
  9. import java.net.ServerSocket;
  10. import java.net.Socket;
  11. import java.util.Properties;
  12. //说明:如果一个类,需要有界面的显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个“窗体类"
  13. //1.定义JFrame窗体中的组件
  14. //2.在构造方法中初始化组件
  15. //3.使用网络编程完成数据的传输(TCP,UDP协议)
  16. //4.实现“发送”按钮的监听点击事件。需要注意的是,文本域拼接数据时,需要自己换行,不要在发送数据时换行。
  17. public class ServerChatMain extends JFrame implements ActionListener, KeyListener {
  18. public static void main(String[] args) {
  19. // 调用构造器
  20. new ServerChatMain();
  21. }
  22. //属性
  23. //文本域
  24. private JTextArea jta;
  25. //滚动条
  26. private JScrollPane jsp;
  27. //面板
  28. private JPanel jp;
  29. //文本框
  30. private JTextField jtf;
  31. //按钮
  32. private JButton jb;
  33. //流
  34. BufferedReader br;
  35. BufferedWriter bw;
  36. //服务端端口号
  37. private static int serverPort;
  38. //静态代码块加载外部配置文件
  39. //特点1:在类加载时,自动执行
  40. //特点2:一个类只会加载一次,因此静态代码块只会执行一次
  41. static {
  42. Properties prop = new Properties();
  43. try {
  44. prop.load(new FileReader("chat.properties"));
  45. serverPort =Integer.parseInt(prop.getProperty("serverPort"));
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. //创建空参构造器
  51. public ServerChatMain(){
  52. //初始化组件
  53. //初始化文本域
  54. jta = new JTextArea();
  55. //设置文本域不可编辑
  56. jta.setEditable(false);
  57. //将文本域添加到滚动条中,实现滚动效果
  58. jsp = new JScrollPane(jta);
  59. //面板
  60. jp = new JPanel();
  61. jtf = new JTextField(15);
  62. jb = new JButton("发送");
  63. //将文本框与按钮添加到面板中
  64. jp.add(jtf);
  65. jp.add(jb);
  66. //将滚动条与面板全部添加到窗体中
  67. this.add(jsp, BorderLayout.CENTER);
  68. this.add(jp, BorderLayout.SOUTH);
  69. //设置 标题,大小,位置,关闭,是否可见
  70. this.setTitle("QQ 服务端");
  71. this.setSize(300,300);
  72. this.setLocation(600,300);
  73. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序退出
  74. this.setVisible(true);
  75. /******************TCP 服务端 start*****************/
  76. //给发送按钮绑定一个监听点击事件
  77. jb.addActionListener(this);
  78. //给文本框绑定一个键盘点击事件
  79. jtf.addKeyListener(this);
  80. //接收客户端数据,并回显到自己的文本域
  81. try {
  82. //1.创建一个服务端的套接字socket
  83. ServerSocket serverSocket = new ServerSocket(serverPort);
  84. //2.等待客户端的链接
  85. Socket socket = serverSocket.accept();//客户端对象
  86. //3.获取socket 通道的输入流(输入流是实现读取数据的,一行一行读取,因此用BufferedReader-->readLine
  87. br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  88. //4.获取socket 通道的输出流(输出流实现写出数据,也是写一行,换一行,刷新)BufferedWriter-->new Line()
  89. //什么时候需要写出数据?当用户点击发送按钮时
  90. bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  91. //循环读取数据,并把它拼接到文本域中
  92. String line = null;
  93. while ((line=br.readLine())!=null){
  94. //将读取的数据拼接到文本域中显示
  95. jta.append(line+System.lineSeparator());
  96. }
  97. //5.关闭serverSocket 通道
  98. serverSocket.close();
  99. } catch (IOException e) {
  100. e.printStackTrace();
  101. }
  102. /******************TCP 服务端 end*****************/
  103. }
  104. //行为
  105. /**
  106. * 重新ActionListener中的1个方法,实现点击 发送键 发送
  107. * @param e
  108. */
  109. @Override
  110. public void actionPerformed(ActionEvent e) {
  111. sendDataToSocket();
  112. }
  113. /**
  114. * 重写KeyListener中的3个方法,实现Enter键发送
  115. * @param e
  116. */
  117. @Override
  118. public void keyPressed(KeyEvent e) {
  119. //回车键
  120. if (e.getKeyCode()== KeyEvent.VK_ENTER){
  121. //发送数据到socket通道
  122. sendDataToSocket();
  123. }
  124. }
  125. @Override
  126. public void keyTyped(KeyEvent e) {
  127. }
  128. @Override
  129. public void keyReleased(KeyEvent e) {
  130. }
  131. //方法功能:发送数据到客户端,并将内容回显到自己的文本域
  132. public void sendDataToSocket(){
  133. //1.获取文本框中的内容
  134. String text = jtf.getText();
  135. //2.拼接需要发送的数据内容
  136. text = "服务端对客户端说:"+text;
  137. //3.自己也需要显示
  138. jta.append(text+System.lineSeparator());
  139. try {
  140. //4.发送
  141. bw.write(text);
  142. bw.newLine();
  143. bw.flush();
  144. //5.清空文本框
  145. jtf.setText("");
  146. } catch (Exception exception) {
  147. exception.printStackTrace();
  148. }
  149. }
  150. }

客户端代码:

  1. package cn.qy.chat;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.KeyEvent;
  7. import java.awt.event.KeyListener;
  8. import java.io.*;
  9. import java.net.Socket;
  10. import java.util.Properties;
  11. //说明:如果一个类,需要有界面的显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个“窗体类
  12. //1.定义JFrame窗体中的组件
  13. //2.在构造方法中初始化组件
  14. public class ClientChatMain extends JFrame implements ActionListener, KeyListener {
  15. public static void main(String[] args) {
  16. // 调用构造器
  17. new ClientChatMain();
  18. }
  19. //属性
  20. //文本域
  21. private JTextArea jta;
  22. //滚动条
  23. private JScrollPane jsp;
  24. //面板
  25. private JPanel jp;
  26. //文本框
  27. private JTextField jtf;
  28. //按钮
  29. private JButton jb;
  30. //流
  31. BufferedReader br;
  32. BufferedWriter bw;
  33. //通信的IP和Port
  34. private static int clientPort;
  35. private static String clientIP;
  36. //静态代码块加载外部配置文件
  37. //特点1:在类加载时,自动执行
  38. //特点2:一个类只会加载一次,因此静态代码块只会执行一次
  39. static {
  40. Properties prop = new Properties();
  41. try {
  42. prop.load(new FileReader("chat.properties"));
  43. clientPort = Integer.parseInt(prop.getProperty("clientPort"));
  44. clientIP = prop.getProperty("clientIP");
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. //创建构造器
  50. public ClientChatMain(){
  51. //初始化组件
  52. //初始化文本域
  53. jta = new JTextArea();
  54. //设置文本域不可编辑
  55. jta.setEditable(false);
  56. //将文本域添加到滚动条中,实现滚动效果
  57. jsp = new JScrollPane(jta);
  58. //面板
  59. jp = new JPanel();
  60. jtf = new JTextField(15);
  61. jb = new JButton("发送");
  62. //将文本框与按钮添加到面板中
  63. jp.add(jtf);
  64. jp.add(jb);
  65. //将滚动条与面板全部添加到窗体中
  66. this.add(jsp, BorderLayout.CENTER);
  67. this.add(jp, BorderLayout.SOUTH);
  68. //设置 标题 大小,位置,关闭,是否可见
  69. this.setTitle("QQ 客户端");
  70. this.setSize(300,300);
  71. this.setLocation(300,300);
  72. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序退出
  73. this.setVisible(true);
  74. /******************TCP 客户端 start*****************/
  75. //给发送按钮绑定一个监听点击事件
  76. jb.addActionListener(this);
  77. //给键盘绑定单击事件
  78. jtf.addKeyListener(this);
  79. //接受服务端数据,并回显到自己的文本域
  80. try {
  81. //1.创建一个客户端的套接字socket
  82. Socket socket = new Socket(clientIP, clientPort);
  83. //2.获取socket 通道的输入流
  84. br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  85. //3.获取socket 通道的输出流
  86. bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  87. //循环读取数据,并把它拼接到文本域中
  88. String line =null;
  89. while ((line=br.readLine())!=null){
  90. jta.append(line+System.lineSeparator());
  91. }
  92. //4.关闭socket 通道
  93. socket.close();
  94. } catch (Exception e) {
  95. e.printStackTrace();
  96. }
  97. /******************TCP 客户端 end*****************/
  98. }
  99. //行为
  100. /**
  101. * 重新ActionListener中的1个方法,实现点击 发送键 发送
  102. * @param e
  103. */
  104. @Override
  105. public void actionPerformed(ActionEvent e) {
  106. sendDataToSocket();
  107. }
  108. /**
  109. * 重写KeyListener中的3个方法,实现Enter键发送
  110. * @param e
  111. */
  112. @Override
  113. public void keyPressed(KeyEvent e) {
  114. if (e.getKeyCode()==KeyEvent.VK_ENTER){
  115. sendDataToSocket();
  116. }
  117. }
  118. @Override
  119. public void keyTyped(KeyEvent e) {
  120. }
  121. @Override
  122. public void keyReleased(KeyEvent e) {
  123. }
  124. //方法功能:发送数据到服务端,并将内容回显到自己的文本域
  125. private void sendDataToSocket(){
  126. //1.获取文本框中的内容
  127. String text = jtf.getText();
  128. //2.拼接需要发送的数据内容
  129. text = "客户端对服务端说:"+text;
  130. //3.自己也需要显示
  131. jta.append(text+System.lineSeparator());
  132. try {
  133. //4.发送
  134. bw.write(text);
  135. bw.newLine();
  136. bw.flush();
  137. //5.清空文本框
  138. jtf.setText("");
  139. } catch (Exception exception) {
  140. exception.printStackTrace();
  141. }
  142. }
  143. }

 启动时,必须先启动服务端,再启动客户端。

最终效果:

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/99166
推荐阅读
相关标签
  

闽ICP备14008679号