日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java聊天室群聊及私聊实现!

發布時間:2023/12/16 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java聊天室群聊及私聊实现! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java聊天室群聊及私聊實現!

一:業務邏輯

  • 連接數據庫,實現注冊登錄賬號的功能
  • 使用serverSocket接收并發送消息實現服務器功能
  • 客戶端使用socket與服務器交互
  • 二:類設計及代碼結構

  • MyMessage類:該類主要用于封裝發送的消息內容
  • ServerSocketTest類:服務器段實現類
  • signup類:通過數據庫實現登錄注冊
  • SocketFrame:聊天主界面類
  • 三:代碼
    Mymessage類代碼:

    package objtalk;import java.io.Serializable; import java.util.ArrayList;import javax.swing.text.StyledDocument;/** 該消息類分為兩種* 一種是實際消息內容* 還有一種是當前群聊的成員信息* */public class MyMessage implements Serializable {// 序列化&&反序列化(用于被傳輸的對象)public static final long serialVersionUID = 1l;public static final int MES_TYPE_PLAIN = 1;//文本消息public static final int MES_TYPE_UPDATE_CLIENTLIST = 2;//更新用戶列表消息private StyledDocument content ;//非文本消息(例如圖片)private ArrayList<String> clientList;//當前群聊成員信息private int mesType = -1;private boolean ifmass=true;//判斷是群聊消息還是私聊信息private String ip="null";//私發message對象ipprivate String usename = "null";public String getIp() {return ip;}public void setIp(String ip) {this.ip = ip;}public MyMessage(Boolean ifmass,int mesType) {this.ifmass=ifmass;this.mesType = mesType;}public int getMesType() {return mesType;}public void setMesType(int mesType) {this.mesType = mesType;}public StyledDocument getContent() {return content;}public void setContent(StyledDocument content) {this.content = content;}public ArrayList<String> getClientList() {return clientList;}public void setClientList(ArrayList<String> clientList) {this.clientList = clientList;}public boolean getisIfmass() {return ifmass;}public void setIfmass(boolean ifmass) {this.ifmass = ifmass;} }

    signup類代碼:

    package objtalk;/*創建一張talk數據表* 表結構為usename和password* */import java.awt.event.ActionEvent;import java.awt.event.ActionListener; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException;import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField;import com.mysql.jdbc.Connection; import com.mysql.jdbc.Statement;public class signup extends JFrame{private JTextField usename = new JTextField();//文本輸入框private JTextField password = new JTextField();private JButton signup = new JButton("注冊");//按鈕private JButton signin = new JButton("登陸");//數據庫信息private String user = "";private String pwd = "";private String url = "";//jdbc:myaql://ip或端口號/需要打開的databaseprivate boolean tag = false;//判斷賬號密碼是否正確public signup() {// TODO Auto-generated constructor stubthis.setSize(300,400);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setLayout(null);this.add(usename);this.add(password);this.add(signin);this.add(signup);usename.setSize(100,30);password.setSize(100,30);signin.setSize(100,50);signup.setSize(100,50);usename.setLocation(100,100);password.setLocation(100,200);signin.setLocation(50,300);signup.setLocation(150,300);try {Class.forName("com.mysql.jdbc.Driver");//開啟數據庫} catch (ClassNotFoundException e2) {// TODO Auto-generated catch blocke2.printStackTrace();}signin.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String useName = usename.getText().toString();String passWord = password.getText().toString();if(useName.isEmpty()||passWord.isEmpty()){JOptionPane.showMessageDialog(null, "請輸入用戶名或密碼", "error",JOptionPane.ERROR_MESSAGE);}else{try {Connection con = (Connection) DriverManager.getConnection(url, user, pwd);//數據庫連Statement stmt = (Statement) con.createStatement();//創建語句對象String sql = "select * from talk";//數據庫語句ResultSet rs = (ResultSet) stmt.executeQuery(sql);//執行語句得到結果,以行的角度表現查詢結果java.sql.ResultSetMetaData rsmd = rs.getMetaData();//結果以列的形式展現while(rs.next()){//按行逐個讀取查詢的內容,next()表示行的移動if(rs.getString(1).equals(useName)&&rs.getString(2).equals(passWord)){tag = true;new SocketFrame().setVisible(true);//跳轉到主界面exits();//關閉當前界面return;}}if(tag==false){JOptionPane.showMessageDialog(null, "賬號密碼錯誤!", "error",JOptionPane.ERROR_MESSAGE);}} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});signup.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubString useName = usename.getText().toString();String passWord = password.getText().toString();if(useName.isEmpty()||passWord.isEmpty()){JOptionPane.showMessageDialog(null, "請輸入用戶名或密碼", "error",JOptionPane.ERROR_MESSAGE);}else{Connection con;try {con = (Connection) DriverManager.getConnection(url, user, pwd);Statement stmt = (Statement) con.createStatement();String sql = "insert talk value('"+useName+"','"+passWord+"');";stmt.executeUpdate(sql);JOptionPane.showMessageDialog(null,"注冊成功", "done",JOptionPane.ERROR_MESSAGE);//stmt.executeQuery(sql);//執行語句得到結果,以行的角度表現查詢結果} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}//數據庫連接,Connection是接口不能用new}}});}public void exits() {this.setVisible(false);}public static void main(String[] args) {new signup().setVisible(true);} }

    SocktFrame類代碼

    package objtalk;import java.awt.BorderLayout; import java.awt.Font; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.SocketAddress; import java.nio.channels.NonWritableChannelException; import java.nio.channels.SelectableChannel; import java.util.ArrayList; import java.util.List;import javax.imageio.ImageIO; import javax.lang.model.element.Element; import javax.swing.AbstractListModel; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.event.AncestorListener; import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.BadLocationException; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument;public class SocketFrame extends JFrame {private JTextPane jtpMes = new JTextPane();//消息框private StyledDocument contentDoc = jtpMes.getStyledDocument();//取出文本(),屬性定義(sas的容器)private JScrollPane jspMes = new JScrollPane(jtpMes);//為消息框添加滑動框private JButton btnSend = new JButton("Send");private JButton btnConnect = new JButton("Connect");private JButton btnSelectimg = new JButton("img");private JTextPane jtpNewMes = new JTextPane();//消息框(可以顯示圖片和文字)private JScrollPane jspNewMes = new JScrollPane(jtpNewMes);//為群聊框添加滑動框private StyledDocument sendDoc = jtpNewMes.getStyledDocument();private JPanel panSend = new JPanel();JPanel btnPan = new JPanel();private Font font = new Font("宋體", Font.PLAIN, 20);private JList<String> listClient = new JList<>();private JScrollPane jspClientList = new JScrollPane(listClient);private Socket socket;private ObjectOutputStream out;private ReadThread reader;//讀取消息線程public SocketFrame() {this.setSize(800, 600);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(EXIT_ON_CLOSE);init();getContentPane().add(jspMes);getContentPane().add(panSend, BorderLayout.SOUTH);getContentPane().add(jspClientList, BorderLayout.EAST);}public void updateListClient(ArrayList list) {//跟新群聊用戶信息listClient.setModel(new ClientListModel(list));}class ClientListModel extends AbstractListModel {//更新list信息ArrayList list;public ClientListModel(ArrayList list) {super();this.list = list;}@Overridepublic Object getElementAt(int arg0) {return list.get(arg0);}@Overridepublic int getSize() {return list.size();}}private void init() {panSend.setLayout(new BorderLayout());panSend.add(jspNewMes,BorderLayout.CENTER);panSend.add(btnPan,BorderLayout.EAST);btnPan.add(btnSend);btnPan.add(btnConnect);btnPan.add(btnSelectimg);jtpMes.setEditable(false);jtpMes.setFont(font);jtpNewMes.setFont(font);btnSend.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent arg0) {String str = jtpNewMes.getText().trim();//得到文本System.out.println(str);if (str != null && str.length() > 0 && socket != null) {SocketAddress address = socket.getRemoteSocketAddress();//得到本地地址String ip = address.toString().substring(1,address.toString().indexOf(":") + 1);//獲得ipSimpleAttributeSet sas = new SimpleAttributeSet();//容器存儲消息體StyleConstants.setFontSize(sas,24);//設置字體try {/*senDoc消息內容會自動從輸入消息框獲取(綁定更新,50行57行代碼實現),這里只是在消息前面添加ip(類似用戶名)*/sendDoc.insertString(0, ip, sas);} catch (BadLocationException e) {// TODO Auto-generated catch blocke.printStackTrace();}MyMessage mes = new MyMessage(true,MyMessage.MES_TYPE_PLAIN);mes.setContent(sendDoc);sendMes(mes);//發送消息try {sendDoc.remove(0, sendDoc.getLength());//去除容器中的內容} catch (BadLocationException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});btnConnect.addActionListener(new ActionListener() {//連接服務器@Overridepublic void actionPerformed(ActionEvent arg0) {if(socket==null){try {socket = new Socket("10.117.45.114", 12345);//具體ip自己設置reader = new ReadThread(socket);reader.start();out = new ObjectOutputStream(socket.getOutputStream());//創建消息輸入流} catch (Exception e) {e.printStackTrace();}}}});btnSelectimg.addActionListener(new ActionListener() {//選區本地圖片存入容器@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJFileChooser fc = new JFileChooser("d:");//文件選擇器FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Image", "jpg","gif");//文件篩選器fc.setFileFilter(filter);int i = fc.showOpenDialog(SocketFrame.this);if(i == JFileChooser.APPROVE_OPTION){try {Image img = ImageIO.read(fc.getSelectedFile());ImageIcon icon = new ImageIcon(img);SimpleAttributeSet sas = new SimpleAttributeSet();//容器StyleConstants.setIcon(sas, icon);//把圖標放入sas容器sendDoc.insertString(sendDoc.getLength(), "icon", sas);//把sas插入文本格式,屬性定義} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (BadLocationException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent arg0) {//關閉主界面后程序退出流關閉if (out != null) {MyMessage mes = new MyMessage(true,MyMessage.MES_TYPE_PLAIN);//mes.setContent("quit");sendMes(mes);reader.stopRun();}}});listClient.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {// TODO Auto-generated method stubsuper.mouseClicked(e);if(e.getClickCount()==2){//雙擊觸發私聊new PrivateDialog(listClient.getSelectedValue().toString()).setVisible(true);}}});}public void append(StyledDocument sd){int caretPosition = jtpMes.getStyledDocument().getLength();caretPosition+=sd.getLength();try {for(int i=0;i<sd.getLength();i++){javax.swing.text.Element e = sd.getCharacterElement(i);if(e.getName().equals("icon")){contentDoc.insertString(contentDoc.getLength(), "icon", e.getAttributes());i+=2;}else{String s = sd.getText(i, 1);contentDoc.insertString(contentDoc.getLength(), s, e.getAttributes());}}contentDoc.insertString(contentDoc.getLength(), "\n", null);} catch (BadLocationException e) {// TODO Auto-generated catch blocke.printStackTrace();}jtpMes.setCaretPosition(caretPosition);}public void sendMes(MyMessage m) {if (out != null) {try {out.reset();//反復發送同一個內容不斷改變的對象需要使用reset(此時為sendDoc)out.writeObject(m);out.flush();} catch (IOException e) {e.printStackTrace();}}}class ReadThread extends Thread {Socket c;boolean flag = true;public ReadThread(Socket c) {this.c = c;}@Overridepublic void run() {try {ObjectInputStream in = new ObjectInputStream((c.getInputStream()));MyMessage newMes = (MyMessage) in.readObject();while (flag) {switch (newMes.getMesType()) {case MyMessage.MES_TYPE_PLAIN:append(newMes.getContent());//將得到的消息添加進聊天框break;case MyMessage.MES_TYPE_UPDATE_CLIENTLIST:updateListClient(newMes.getClientList());//更新聊天人信息break;}//將輸入流和message對象初始化供下次使用in = new ObjectInputStream((c.getInputStream()));newMes = (MyMessage) in.readObject();}} catch (Exception e) {e.printStackTrace();}}public void stopRun() {flag = false;}}class PrivateDialog extends JDialog{//單獨對話框private JTextPane jtpPriMes = new JTextPane();private JScrollPane jspPriMes = new JScrollPane(jtpPriMes);private JButton btnPriSend = new JButton("Send");private JButton btnselect = new JButton("select");private JPanel panFun = new JPanel();private String ip;public PrivateDialog(String ip) {// TODO Auto-generated constructor stubthis.ip = ip;this.setTitle(ip);this.setSize(400, 300);this.setLocationRelativeTo(null);init();this.add(panFun);}private void init() {panFun.add(jtpPriMes);panFun.add(btnPriSend);panFun.add(btnselect);btnPriSend.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubString str = jtpPriMes.getText().trim();if(str!=null&&str.length()>0&&socket!=null){MyMessage mes = new MyMessage(false,MyMessage.MES_TYPE_PLAIN);mes.setIp(ip);mes.setContent(jtpPriMes.getStyledDocument());sendMes(mes);}}});btnselect.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJFileChooser fc = new JFileChooser("d:");FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Image", "jpg","gif");//文件篩選器fc.setFileFilter(filter);int i = fc.showOpenDialog(SocketFrame.this);if(i == JFileChooser.APPROVE_OPTION){try {Image img = ImageIO.read(fc.getSelectedFile());ImageIcon icon = new ImageIcon(img);SimpleAttributeSet sas = new SimpleAttributeSet();//容器StyleConstants.setIcon(sas, icon);//把圖標放入sas容器jtpPriMes.getStyledDocument().insertString(jtpPriMes.getStyledDocument().getLength(), "icon", sas);//把sas插入文本格式,屬性定義} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (BadLocationException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});}}}

    ServerSocketTest代碼

    package objtalk;import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator;import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument;import org.omg.CORBA.SystemException;public class ServerSocketTest {ServerSocket server;HashSet<Socket> clientSet = new HashSet<>();public ServerSocketTest() {try {server = new ServerSocket(12345);} catch (IOException e) {e.printStackTrace();}}public void work() {int no = 0;//連接服務器的個數try {while (true) {Socket client = server.accept();clientSet.add(client);SendUpdateClientList();no++;new ClientThread(client, no).start();}} catch (IOException e) {e.printStackTrace();}}public void SendUpdateClientList() {//發送用戶變更的消息,用戶退出和加入的監聽MyMessage mes = new MyMessage(true,MyMessage.MES_TYPE_UPDATE_CLIENTLIST);mes.setClientList(getClientList());massMes(mes);}public void massMes(MyMessage mes) {//群發消息Iterator<Socket> it = clientSet.iterator();while (it.hasNext()) {sendMes(it.next(), mes);}}public void singleMes(MyMessage mes){//單發消息for(Socket s : clientSet){if(s.getRemoteSocketAddress().toString().equals(mes.getIp())){//String判等必須用equalssendMes(s, mes);break;}}}public void sendMes(Socket s, MyMessage mes) {ObjectOutputStream out;try {out = new ObjectOutputStream(s.getOutputStream());out.writeObject(mes);out.flush();} catch (IOException e1) {e1.printStackTrace();}}public ArrayList<String> getClientList() {ArrayList<String> list = null;if (clientSet.size() > 0) {list = new ArrayList<String>();Iterator<Socket> it = clientSet.iterator();int index = 0;while (it.hasNext()) {list.add(it.next().getRemoteSocketAddress().toString());}}return list;}class ClientThread extends Thread {Socket c;int no;public ClientThread(Socket c, int no) {super();this.c = c;this.no = no;}@Overridepublic void run() {try (ObjectInputStream in = new ObjectInputStream((c.getInputStream()));) {MyMessage newMes = (MyMessage) in.readObject();while (newMes.getContent()!=null) {//不斷接收發來的消息if(newMes.getisIfmass()==true){massMes(newMes);System.out.println(newMes.getContent().getText(0,newMes.getContent().getLength() ));}else{singleMes(newMes);}newMes = (MyMessage) in.readObject();}} catch (Exception e) {e.printStackTrace();} finally {try {c.close();} catch (IOException e) {e.printStackTrace();}clientSet.remove(c);//用戶退出后SendUpdateClientList();}}}public static void main(String[] args) {new ServerSocketTest().work();}}

    四:使用方法:

  • 開啟ServerSocketTest類(打開服務器)
  • 開啟signUp類,注冊,登錄,連接,開始聊天(可以多開幾個實現群聊)
    五:項目github地址
    https://github.com/Chaos1874/javaTalk
  • 總結

    以上是生活随笔為你收集整理的java聊天室群聊及私聊实现!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。