博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多人聊天
阅读量:6116 次
发布时间:2019-06-21

本文共 12112 字,大约阅读时间需要 40 分钟。

hot3.png

 

package com.socketForm;

import java.awt.BorderLayout;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOError;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;

import javax.swing.DefaultListModel;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.border.TitledBorder;
/**
 * 聊天程序服务器窗口
 * dingzhen
 * 2016-03-09
 */
public class ServerForm extends JFrame{
 private static final long serialVersionUID = 1L;
 private static final int PORT = 9090;        //端口号
 private JTextArea area;            //用户放用户信息的显示区
 private DefaultListModel lm;          //列表对像,用户保存用户登录信息
 private Map<String,Object> usersMap = new HashMap<String, Object>(); //保存所有在线用户的名称和Socket
 public ServerForm() throws Exception{
  area = new JTextArea();
  area.setEditable(false);
  lm = new DefaultListModel();
  getContentPane().add(new JScrollPane(area));
  
  JList list= new JList(lm);
  JScrollPane jc = new JScrollPane(list);
  jc.setPreferredSize(new Dimension(100,this.getHeight()));
  jc.setBorder(new TitledBorder("在线"));
  getContentPane().add(jc,BorderLayout.EAST);
  JMenuBar bar = new JMenuBar();         //声明一组菜单
  JMenu    m   = new JMenu("控制");
  bar.add(m);
  m.setMnemonic('C');
  final JMenuItem run = new JMenuItem("开启");
  run.setAccelerator(KeyStroke.getKeyStroke('R',KeyEvent.CTRL_MASK));  //设置快捷键
  run.setActionCommand("run");
  m.add(run);

  

  m.addSeparator();
  JMenuItem exit = new JMenuItem("退出");
  exit.setAccelerator(KeyStroke.getKeyStroke('E',KeyEvent.CTRL_MASK));
  exit.setActionCommand("exit");
  m.add(exit);
  setJMenuBar(bar);
  
  ActionListener al = new ActionListener(){      //添加一个内部类,以启动服务器
   public void actionPerformed(ActionEvent e) {
    if(e.getActionCommand().equals("run")){
     startServer();
     run.setEnabled(false);
    }else{
     System.exit(0);
    }
   }
  };
  run.addActionListener(al);
  exit.addActionListener(al);
  
  final int winWidth  = 500;
  final int winHeight = 400;
     Toolkit toolkit = Toolkit.getDefaultToolkit();
     int width  = (int)toolkit.getScreenSize().getWidth();
     int height = (int)toolkit.getScreenSize().getHeight();
     setTitle("这是服务器");
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(width/2-winWidth/2,height/2-winHeight/2,winWidth, winHeight);   //在屏幕的中间显示
  setVisible(true);
  
 }
 public static void main(String[] args) throws Exception {
  JFrame.setDefaultLookAndFeelDecorated(true);
  new ServerForm();
 }
 /**
  * 启动服务器
  */
 public void startServer(){
  try{
   System.err.println("启动服务...");
   ServerSocket server = new ServerSocket(PORT);
   area.append("启动服务:"+server);
   new ServerThread(server).start();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 /**
  * 启动服务的线程
  */
 class ServerThread extends Thread{
  private ServerSocket server;
  public ServerThread(ServerSocket server) {
   this.server = server;
  }
  public void run() {
   try{
    while(true){
     Socket socketClient = server.accept();      //等待获取客户端的连接
     Scanner sc   = new Scanner(socketClient.getInputStream()); //获取用户端输入流
     if(sc.hasNextLine()){
      String userName = sc.nextLine();
      area.append("\r\n用户:["+userName+"]登录,"+socketClient);
      lm.addElement(userName);
      new ClientThread(socketClient);        //启动这个线程
      msgAll(userName);           //通知所有人有人登录
      msgSelf(socketClient);             //通知当前登录的人,有多少人在线
      usersMap.put(userName,socketClient);
      System.err.println("一个线程已经启动....");
     }
     
     
    }
   }catch(Exception e){
    e.printStackTrace();
   }
  }
 }
 /**
  * 服务器开始客户端的线程
  */
 class ClientThread extends Thread{
  private Socket client;
  public ClientThread(Socket client) {
   System.err.println("初始。。。。。");
   this.client = client;
   start();
  }
  public void run(){
   System.err.println("一个线程启动成功。。。。");
   try{
    Scanner sc = new Scanner(client.getInputStream());
    while(sc.hasNextLine()){   //这儿接收用户的信息,格式如下:命令@#给谁@#消息@#自己
     String msg = sc.nextLine();
     System.err.println(msg);
     String[] msgs = msg.split("@#");
     if(msgs[0].equals("exit")){       //结束此线程的运行,停止会话
      System.err.println("退出人:"+msgs[3]);    //还要通知甩有人有人退出,并删除所有人列表中的自己
      usersMap.remove(msgs[3]);      //从列表中删除此用户的信息
      lm.removeElement(msgs[3]);      //从服务器的显示列中删除
      area.append("\r\n用户["+msgs[3]+"]退出了。");
      sendExitMsgToAll(msgs);
      break;
     }else{
      sendMsgToSb(msgs);        //发消息给某人
     }
    }
   }catch(Exception e){
    e.printStackTrace();
   }
  }
 }
 /**
  * 通知所有人,有人登录
  * 写出信息的类型为:
  * 类型:通知(cmd)|消息(msg)@#谁的通知SomeBody@#消息文本MSG
  */
 private void msgAll(String userName){
  try{
   Iterator<Object> it = usersMap.values().iterator();
   while(it.hasNext()){
    Socket s = (Socket)it.next();
    try{
     PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
     String msg = "@#用户["+userName+"]登录了.";
     pw.println(msg);
     pw.flush();
     msg = ";
     pw.println(msg);
     pw.flush();
    }catch(IOException e){
     e.printStackTrace();
    }
   }
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 /**
  * 通知当前登录的人有多少人在线
  */
 private void msgSelf(Socket client){
  try{
   PrintWriter pw = new PrintWriter(client.getOutputStream(),true);
   Iterator<String> it = usersMap.keySet().iterator();
   while(it.hasNext()){
    String msg = "();
    pw.println(msg);
   }
  }catch(IOException e){
   e.printStackTrace();
  }
 }
 /**
  * 发消息给某人
  */
 private void sendMsgToSb(String[] msgs) throws IOException{
  if(msgs[1].equals("全部")){           //发消息给所有人
   Iterator<String> userNames = usersMap.keySet().iterator();
   while(userNames.hasNext()){
    String userName = userNames.next();
    if(!userName.equals(msgs[3])){        //如果不是自己
     Socket s = (Socket)usersMap.get(userName);
     PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
     String str = "];
     pw.println(str);
     pw.flush();
    }
   }
  }else{
   Socket s = (Socket)usersMap.get(msgs[1]);       
   PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
   String str = "];
   pw.println(str);
   pw.flush();
  }
 }
 /**
  * 通知所有人有人退出
  */
 private void sendExitMsgToAll(String[] msgs) throws IOException{
  Iterator<String> userNames = usersMap.keySet().iterator();
  while(userNames.hasNext()){
   String userName = userNames.next();
   Socket s = (Socket)usersMap.get(userName);
   PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
   String str = "@#用户["+msgs[3]+"]退出了。";
   pw.println(str);
   pw.flush();
   str = "];
   pw.println(str);
   pw.flush();
  }
 }
}

package com.socketForm;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
/**
 * 客户端程序
 * @author dingzhen
 * @version 2016-03-09
 */
public class ClientForm extends JFrame implements ActionListener{
 private static final long serialVersionUID = 1L;
 private static  String HOST = "127.0.0.1";       //服务器地址
 private static  int    PORT = 9090;         //端口号
 private JTextField userName;          //启用标识
 private DefaultListModel lm;          //在线用户列表
 private JList list;
 private JTextField msg;            //发消息框
 private JTextArea allMsg = new JTextArea();       //收消息框
 public ClientForm() throws Exception {
  addJMenuBar();              //设置菜单
  userName = new JTextField(10);
  JPanel  p= new JPanel();
  p.add(new JLabel("用户标识:"));
  p.add(userName);
  JButton conn = new JButton("连接");
  conn.setActionCommand("c");
  conn.addActionListener(this);
  p.add(conn);
  
  JButton exitBtn = new JButton("退出");
  exitBtn.setActionCommand("exit");
  exitBtn.addActionListener(this);
  p.add(exitBtn);
  p.setBorder(new LineBorder(Color.GRAY));
  //以下是中间的面板
  JPanel center = new JPanel(new BorderLayout());
  lm = new DefaultListModel();
  list = new JList(lm);
  lm.addElement("全部");
  list.setSelectedIndex(0);             //默认选中全部
  list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  list.setVisibleRowCount(2);
  JScrollPane jc = new JScrollPane(list);
  jc.setBorder(new TitledBorder("在线"));
  jc.setPreferredSize(new Dimension(70,center.getHeight()));
  center.add(jc,BorderLayout.EAST);
  
  JPanel send  = new JPanel();
  send.add(new JLabel("消息:"));
  msg = new JTextField(20);
  send.add(msg);
  JButton sendBtn  = new JButton("发送");
  sendBtn.setActionCommand("send");
  sendBtn.addActionListener(this);
  send.add(sendBtn);
  center.add(send,BorderLayout.SOUTH);
  allMsg.setEditable(false);
  center.add(new JScrollPane(allMsg));
  Container c = getContentPane();
  c.add(p,BorderLayout.NORTH);
  c.add(center,BorderLayout.CENTER);
  addWindowListener(new WindowAdapter() {       //当用户退出时,先要通知所有人,有人退出
   public void windowClosing(WindowEvent arg0) {
    sendExitMsg();
   }
  });
  setBounds(300, 300, 400, 300);
  setVisible(true);
 }
 
 public static void main(String[] args) throws Exception {
  JFrame.setDefaultLookAndFeelDecorated(true);
  new ClientForm();
 }
 public void actionPerformed(ActionEvent e) {
  if(e.getActionCommand().equals("c")){
   System.err.println("连接...");
   connecting();
  }else if(e.getActionCommand().equals("send")){
   String msg = "();
   System.err.println(">发出的消息为:"+msg);
   pw.println(msg);
   pw.flush();
  }else if(e.getActionCommand().equals("exit")){    //用户要退出
   sendExitMsg();
  }
 }
 /**
  * 发送退出的消息
  */
 private void sendExitMsg(){
  if(client==null){
   System.exit(0);
   return;
  }
  String msg = "exit@#全部@#null@#"+userName.getText();
  System.err.println("退出:"+msg);
  pw.println(msg);
  pw.flush();
  System.exit(0);
 }
 /**
  * 创建一个用户连接
  */
 private Socket client;            //声明一个客户端的连接
 private PrintWriter pw;
 private void connecting(){
  try{
   System.err.println(HOST+","+PORT);
   client= new Socket(HOST,PORT);
   String userName = this.userName.getText();      //获取用户标识
   pw = new PrintWriter(client.getOutputStream(),true);
   pw.println(userName);
   this.setTitle("用户["+userName+"]在线...");
   new ClientThread().start();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 /**
  * 用以下线程来读取服务器发送来的信息
  */
 class ClientThread extends Thread{
  public void run() {
   try{
    Scanner sc = new Scanner(client.getInputStream());
    while(sc.hasNextLine()){
     String str = sc.nextLine();
     System.err.println("客户端接收到的消息 :"+str);
     String[] msg = str.split("@#");
     if(msg[0].equals("msg")){      //开头不是msg就是cmd命令
      if(msg[1].equals("server")){
       str = "[通知]:"+msg[2];
      }else{
       str = "["+msg[1]+"]说:"+msg[2];
      }
      allMsg.append("\r\n"+str);
     }else if(msg[0].equals("cmdAdd")){      //说明有人登录
      lm.addElement(msg[2]);
     }else if(msg[0].equals("cmdRed")){      //说明有人退出
      lm.removeElement(msg[2]);
     }
    }
   }catch(IOException e){
    e.printStackTrace();
   }
  }
 }
 /**
  * 添加菜单,控制选项,可以设置服务器及端口号
  */
 private void addJMenuBar(){
  JMenuBar bar = new JMenuBar();
  JMenu    m   = new JMenu("选项");
  JMenuItem mi = new JMenuItem("设置");
  JMenuItem help = new JMenuItem("帮助");
  mi.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    final JDialog set = new JDialog(ClientForm.this,true);
    set.setBounds(ClientForm.this.getX(),ClientForm.this.getY(), 300, 100);
    set.setLayout(new FlowLayout());
    JButton btn = new JButton("设置");
    final JTextField host = new JTextField(10);
    host.setText("127.0.0.1");
    final JTextField port = new JTextField(5);
    port.setText("9090");
    btn.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent arg0) {
      ClientForm.HOST = host.getText();
      ClientForm.PORT = Integer.parseInt(port.getText());
      System.err.println(ClientForm.HOST);
      set.dispose();   //关闭且销毁
     }
    });
    set.add(new JLabel("服务器:"));
    set.add(host);
    set.add(new JLabel(":"));
    set.add(port);
    set.add(btn);
    set.setVisible(true);
   }
  });
  help.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    JDialog set = new JDialog(ClientForm.this,true);
    set.setBounds(ClientForm.this.getX(),ClientForm.this.getY(), 300, 100);
    JLabel jl = new JLabel("版权所有@dingzhen 2016-03-09");
    set.add(jl);
    set.setVisible(true);
   }
  });
  bar.add(m);
  m.add(mi);
  m.add(help);
  this.setJMenuBar(bar);
 }
}

转载于:https://my.oschina.net/dtz/blog/633574

你可能感兴趣的文章
CodeCombat森林关卡Python代码
查看>>
第一个应用程序HelloWorld
查看>>
(二)Spring Boot 起步入门(翻译自Spring Boot官方教程文档)1.5.9.RELEASE
查看>>
Android Annotation扫盲笔记
查看>>
React 整洁代码最佳实践
查看>>
聊聊架构设计做些什么来谈如何成为架构师
查看>>
Java并发编程73道面试题及答案
查看>>
移动端架构的几点思考
查看>>
Tomcat与Spring中的事件机制详解
查看>>
Spark综合使用及用户行为案例区域内热门商品统计分析实战-Spark商业应用实战...
查看>>
初学者自学前端须知
查看>>
Retrofit 源码剖析-深入
查看>>
企业级负载平衡简介(转)
查看>>
ICCV2017 论文浏览记录
查看>>
科技巨头的交通争夺战
查看>>
当中兴安卓手机遇上农行音频通用K宝 -- 卡在“正在通讯”,一直加载中
查看>>
Shell基础之-正则表达式
查看>>
JavaScript异步之Generator、async、await
查看>>
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>