2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 高级API快速入门之群聊天室【09】

高级API快速入门之群聊天室【09】

时间:2024-03-14 00:37:45

相关推荐

高级API快速入门之群聊天室【09】

一、控制台版本的群聊天室

其原理就是:通过死循环进行保存连接服务器的客户端,并创建一个容器来保存所有连接服务器的客户端

服务器:

package com.zking.chat;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import .ServerSocket;import .Socket;import java.util.Vector;/*** qq群的服务器* * @author Administrator*/public class ServerChat {public static void main(String[] args) throws Exception {System.out.println("---------------------服务器--------------------");// 创建一个服务器ServerSocket ss = new ServerSocket(8989);// 无线去接收客户端的连接(需要使用一个容器去保存所有连接服务器的客户端)System.out.println("服务器已启动,端口号为8989");// 通过死循环进行保存连接服务器的客户端// 创建一个容器来保存所有连接服务器的客户端Vector<Socket> vc = new Vector<Socket>();Socket sk = null;while (true) {// 接收客户端sk = ss.accept();// 来一个System.out.println("某客户端上线了...");// 加一个到Vc中vc.add(sk);System.out.println("当前QQ群已加入新成员,目前有: " + vc.size());// 实例化无线读取全部客户端发送过来的消息new Thread(new ServerReadTread(vc, sk)).start();}// 关闭资源}}// 自定义线程类 无线接收已成功连接服务器的客户端发送的消息class ServerReadTread implements Runnable {private Socket sk = null;private Vector<Socket> vc = null;public ServerReadTread(Vector<Socket> vc, Socket sk) {this.vc = vc;this.sk = sk;}@Overridepublic void run() {// 无线接收客户端的消息while (true) {// 输入流try {if (sk != null) {InputStream is = sk.getInputStream();InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);String content = br.readLine();System.out.println("客户端说: " + content);// 问题:如何将content内容转发给QQ群中其他人。System.out.println("vc: " + vc.size());for (Socket socket : vc) {if (socket != null) {// 判断非空// 排除自己if (socket != sk) {// 输出流OutputStream os = socket.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(os);BufferedWriter bw = new BufferedWriter(osw);bw.write(content);bw.newLine();bw.flush();}}}}} catch (Exception e) {e.printStackTrace();}}}}

客户端:

package com.zking.chat;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import .Socket;import java.util.Scanner;/*** 客户端的角色* * @author Administrator**/public class ClientChat {public static void main(String[] args) throws Exception {System.out.println("---------------------客户端--------------------");// 连接服务器Socket sk = new Socket("127.0.0.1", 8989);System.out.println("连接成功");// 获取输出流 编写信息到网络中 让服务器去读取new Thread(new ClientChatThreadWriter(sk)).start();new Thread(new ClientChatThreadReader(sk)).start();}}//无线写入class ClientChatThreadWriter implements Runnable{Socket sk = null;public ClientChatThreadWriter(Socket sk) {this.sk = sk;}@Overridepublic void run() {Scanner sc = new Scanner(System.in);while(true) {try {OutputStream os = sk.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(os);BufferedWriter bw = new BufferedWriter(osw);System.out.println("请输入发送的内容");String content = sc.next();bw.write(content);bw.newLine();bw.flush();if("bye".equalsIgnoreCase(content)) {break;}} catch (Exception e) {// TODO: handle exception}}}}//无限读取class ClientChatThreadReader implements Runnable{Socket sk = null;public ClientChatThreadReader(Socket sk) {this.sk = sk;}@Overridepublic void run() {while(true) {try {InputStream is = sk.getInputStream();InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);String content = br.readLine();System.out.println("某客户端说: "+content);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

二、窗体版本的群聊天室

其原理就是:有一个客户发送消息,然后通过服务器保存消息发送给其他客户,然后其他的客户接收消息

服务器:

package com.zking.files_09;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowEvent;import java.awt.event.WindowListener;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import .ServerSocket;import .Socket;import java.util.Date;import java.util.Scanner;import java.util.Vector;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.UIManager;public class MyServer extends JFrame {private ServerSocket ss = null;private Socket sk = null;private OutputStream os = null;private InputStream is = null;private InputStreamReader isr = null;private BufferedReader br = null;private OutputStreamWriter osw = null;private BufferedWriter bw = null;private Vector<Socket> vc = null;private JPanel jpa = new JPanel(null);private JLabel jla = new JLabel("服务器");private JLabel jlb = new JLabel("端 口");private JTextField jtfa = new JTextField(15);private JButton jba = new JButton("发送连接");private JTextArea jta = new JTextArea(20, 30);private JScrollPane jsp = new JScrollPane(jta);private JTextField jtfb = new JTextField(15);private JButton jbb = new JButton("发送");//private JButton jbc = new JButton("接收");public MyServer() {this.setTitle("");this.setSize(620, 620);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);jla.setBounds(240, 0, 200, 100);jla.setFont(new Font("华文楷体", Font.BOLD, 45));jpa.add(jla);jlb.setBounds(50, 100, 60, 30);jlb.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jlb);jtfa.setBounds(130, 100, 250, 30);jtfa.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jtfa);jtfa.setText("9090");jba.setBounds(400, 100, 150, 30);jba.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jba);jta.setFont(new Font("华文隶书", Font.BOLD, 30));jsp.setBounds(10, 150, 590, 310);jsp.setFont(new Font("华文楷体", Font.BOLD, 30));jpa.add(jsp);jta.setEditable(false);jtfb.setBounds(70, 500, 250, 30);jtfb.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jtfb);jbb.setBounds(360, 500, 130, 30);jbb.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jbb);this.getContentPane().add(jpa);jba.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int port = Integer.parseInt(jtfb.getText());jta.append("服务器正在打开!\n");// 端口号不能为1024之内(系统端口号或是保留端口号)也不能为1433(sqlserver端口号)if (port > 1024 && port != 1433) {try {// 创建服务器,将文本框中的内容获取并启动ss = new ServerSocket(port);// 创建一个集合拿到数据Vector<Socket> vc = new Vector<Socket>();System.out.println(vc);new Thread() {public void run() {while (true) {try {sk = ss.accept();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}vc.add(sk);jta.append("与客户端连接成功!\n");jtfb.setEnabled(false);jta.append("有客户端连接:" + sk.getInetAddress().getHostName() + "\n");new ServerThread0(vc,sk).start();}};}.start();} catch (Exception e2) {// e2.printStackTrace();}} else {JOptionPane.showMessageDialog(null, "端口号不能为1024之内(系统端口号或是保留端口号)也不能为1433(sqlserver端口号)");}}});jbb.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {OutputStream os = sk.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(os);BufferedWriter bw = new BufferedWriter(osw);bw.write(jtfb.getText());bw.newLine();bw.flush();} catch (Exception e1) {e1.printStackTrace();}jta.append("自己\t"+jtfb.getText()+"\n");jtfb.setText("");}});class ServerReadTread implements Runnable {private Socket sk = null;private Vector<Socket> vc = null;public ServerReadTread(Vector<Socket> vc, Socket sk) {this.vc = vc;this.sk = sk;}@Overridepublic void run() {// 无线接收客户端的消息while (true) {// 输入流try {String text = jtfb.getText();if (sk != null) {is = sk.getInputStream();isr = new InputStreamReader(is);br = new BufferedReader(isr);for (Socket socket : vc) {if (socket != null) {// 判断非空// 排除自己if (socket != sk) {// 输出流OutputStream os = socket.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(os);BufferedWriter bw = new BufferedWriter(osw);bw.write(text);bw.newLine();bw.flush();jta.append("我:" + text + "\n");}}}}} catch (Exception e) {e.printStackTrace();}}}}this.setVisible(true);}public static void main(String[] args) {try {UIManager.setLookAndFeel("com.jtattoo.plaf.mcwin.McWinLookAndFeel");} catch (Exception e) {e.printStackTrace();}new MyServer();}}class ServerThread0 extends Thread{//套接字private Socket sk =null;//数组private Vector<Socket> vc =null;/*** 构造方法进行赋值* @param sk 套接字* @param vc 数组*/public ServerThread0(Vector<Socket> vc,Socket sk) {this.vc = vc;this.sk = sk;}@Overridepublic void run() {while(true) {try {//获取消息InputStream is = sk.getInputStream();InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);//读取一整行String r=br.readLine()+"/"+sk.getInetAddress().getHostName();//把当前电脑名字用/分割开发送到网络for (Socket s : vc) {//不能没有对象发送if(s!=null) {//不能发送给自己if(s!=sk) {//发送消息OutputStream os = s.getOutputStream();OutputStreamWriter osw =new OutputStreamWriter(os);BufferedWriter bw =new BufferedWriter(osw);//把服务器获取到的客户端内容写入返回给另一个客户端bw.write(r);bw.newLine();bw.flush();}}}////通过条件进行自我关闭//if("bye".equals(r)) {////清除数据//vc.remove(0);////进行结束//break;//}} catch (Exception e) {//系统处理异常//e.printStackTrace();}}}}

客户端:

package com.zking.files_09;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowEvent;import java.awt.event.WindowListener;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import .Socket;import java.util.Date;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.UIManager;public class MyClinet extends JFrame {private Socket sk = null;private OutputStream os = null;private InputStream is = null;private InputStreamReader isr = null;private BufferedReader br = null;private OutputStreamWriter osw = null;private BufferedWriter bw = null;private JPanel jpa = new JPanel(null);private JLabel jla = new JLabel("客户端");private JLabel jlb = new JLabel("IP:");private JTextField jtfa = new JTextField(15);private JLabel jlc = new JLabel("端口:");private JTextField jtfb = new JTextField(15);private JButton jba = new JButton("连接");private JTextArea jta = new JTextArea(20, 30);private JScrollPane jsp = new JScrollPane(jta);private JTextField jtfc = new JTextField(15);private JButton jbb = new JButton("发送");public MyClinet() {this.setTitle("");this.setSize(620, 620);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);jla.setBounds(240, 0, 200, 100);jla.setFont(new Font("华文楷体", Font.BOLD, 45));jpa.add(jla);jlb.setBounds(50, 100, 100, 30);jlb.setFont(new Font("华文楷体", Font.BOLD, 15));jpa.add(jlb);jtfa.setBounds(90, 100, 150, 30);jtfa.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jtfa);jtfa.setText("127.0.0.1");jlc.setBounds(260, 100, 60, 30);jlc.setFont(new Font("华文楷体", Font.BOLD, 15));jpa.add(jlc);jtfb.setBounds(310, 100, 150, 30);jtfb.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jtfb);jba.setBounds(480, 100, 100, 30);jba.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jba);jta.setFont(new Font("华文隶书", Font.BOLD, 30));jsp.setBounds(10, 150, 590, 310);jsp.setFont(new Font("华文楷体", Font.BOLD, 30));jpa.add(jsp);jta.setEditable(false);jtfc.setBounds(70, 500, 250, 30);jtfc.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jtfc);jbb.setBounds(360, 500, 130, 30);jbb.setFont(new Font("华文楷体", Font.BOLD, 20));jpa.add(jbb);this.getContentPane().add(jpa);jba.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {jta.append("客户端正在连接...\n");String address = jtfa.getText();int port = Integer.parseInt(jtfb.getText());if(port>1024 && port!=1433) {try {sk = new Socket(address, port);jtfa.setEnabled(false);jtfb.setEnabled(false);} catch (Exception e2) {}if(sk!=null) {jba.setEnabled(false);}else {JOptionPane.showMessageDialog(null, "未连接上!");}}else {JOptionPane.showMessageDialog(null, "端口号不能为1024之内(系统端口号或是保留端口号)也不能为1433(sqlserver端口号)");}//创建一个人来无限等待消息new Thread() {public void run() {while(true) {try {InputStream is = sk.getInputStream();InputStreamReader isr =new InputStreamReader(is);BufferedReader br =new BufferedReader(isr);String s =br.readLine();//读取网络发送的消息String name =s.substring(s.lastIndexOf("/")+1);String read =s.substring(0,s.lastIndexOf("/"));jta.append("\t\t"+name+"\t\t"+read+"\n");} catch (Exception e) {e.printStackTrace();}}};}.start();}});jbb.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String text = jtfc.getText();if (sk != null) {try {// 获取界面连接os = sk.getOutputStream();// 字节流osw = new OutputStreamWriter(os);// 字符流FileWriter 缓冲流bw = new BufferedWriter(osw);bw.write(text);bw.newLine();bw.flush();jta.append("我:" + text + "\n");} catch (Exception e2) {//e2.printStackTrace();}} else {JOptionPane.showMessageDialog(null, "请先获取连接....");}}});this.setVisible(true);}public static void main(String[] args) {try {UIManager.setLookAndFeel("com.jtattoo.plaf.mcwin.McWinLookAndFeel");} catch (Exception e) {//e.printStackTrace();}new MyClinet();}}

个人总结:

群聊天室简单来说就是:一个服务器多个客户端,服务器负责接收客户端发送的消息,再将接收到的消息发送给除发送消息以外的所有客户端。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。