2015/8/6/Swing/线程/服务器对多个客户端通讯
2015-08-07 18:07
363 查看
程序例子
程序例子
package com.baidu.imSwing; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.DefaultListModel; import javax.swing.JButton; import java.awt.event.ActionListener; 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 java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.awt.event.ActionEvent; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JList; /** * 这个函数的作用是监听所有客户端发送过来的信息,可以将服务端发送过来的信息转发给所有的客户端 * 不能实现客户端之间的通信只能是客户端与服务器之间的通信 * @author Administrator * */ public class MyServer extends JFrame { private JPanel contentPane; private Socket socket; private JTextArea textArea; private DefaultListModel<String> model; private ArrayList<Socket> sockets; private JList list; private boolean isRuning; public boolean isRuning() { return isRuning; } public void setRuning(boolean isRuning) { this.isRuning = isRuning; } /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MyServer frame = new MyServer(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public MyServer() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 451, 445); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); /** * 启动服务器,并等待客户端的链接将客户端的端口地址放入ArrayList数组内方便调用 * 并为每个端口创建一个新的线程用于监听该端口发送过来的信息 */ JButton btnNewButton = new JButton("启动服务"); btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { /* * 创建一个匿名内部类,一个新的线程等价于 * Runnable run=new Runnable() { * public void run() { * 方法的重写 * } * }; * Thread t=new Thread(); * t.start(); * 这个线程专门等待客户端连接服务器 */ isRuning=true; new Thread(new Runnable() { @Override public void run() { //重写run方法 try { System.out.println("服务器启动"); ServerSocket server=new ServerSocket(8080); //创建服务端,监听8080端口 sockets=new ArrayList<>(); //创建一个ArrayList数组 /* * 当一个客户端进入到服务器时,服务器开始监听该客户端,并将该客户端端口放入sockets数组中 * 创建一个新的线程去读取从该端口发送过来的数据 * 有多个客户端进入时,就会创建多个线程去监听,并读取从客户端发送过来的数据 */ while(isRuning){ //程序运行时 Socket socket= server.accept(); //侦听并接受到此套接字的连接 sockets.add(socket); //将端口加入到数组里 System.out.println("有连接进入服务器"); Thread myRead=new Thread(new MyServerRead(MyServer.this,socket)); myRead.start(); //启动线程 } } catch (IOException e1) { e1.printStackTrace(); } } }).start();; //启动线程 } }); btnNewButton.setBounds(27, 10, 243, 70); contentPane.add(btnNewButton); JButton btnNewButton_1 = new JButton("发送"); btnNewButton_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { try { model.addElement(InetAddress.getLocalHost().getHostAddress()+textArea.getText()); } catch (UnknownHostException e) { e.printStackTrace(); } write(); //调用write方法,点击button就发送数据 } }); btnNewButton_1.setBounds(306, 340, 93, 57); contentPane.add(btnNewButton_1); /** * 创建一个文本输入区,可以通过调用textArea.getText()方法获得文本内容 */ textArea= new JTextArea(); textArea.setBounds(27, 340, 243, 57); contentPane.add(textArea); /** * 创建一个列表并用默认的DefaultListModel来维护列表 */ model=new DefaultListModel<>(); //用于获取列表中每个单元格的值以及列表的长度 list= new JList(); //构造一个具有空的、只读模型的 JList list.setModel(model); //返回保存由 JList 组件显示的项列表的数据模型 list.setBounds(27, 92, 243, 226); contentPane.add(list); } /** * 用来读取监听端口的内容 * 将监听到的信息添加到列表上 * @param socket */ public void read(Socket socket){ if (socket.isConnected()) { //判断端口是否连接,连接返回true try { InputStream is=socket.getInputStream(); //创建一个输入流 BufferedReader br=new BufferedReader(new InputStreamReader(is));//创建一个输入缓冲区域缓冲字符流 String line=br.readLine(); //读一行文本 //将指定组件添加到此类表的末尾;即将读取到的内容添加到这个列表的末尾 model.addElement(socket.getInetAddress().getHostAddress() + " " + line); System.out.println("客户端:"+line); } catch (IOException e) { e.printStackTrace(); } }else{ sockets.remove(socket); //没有连接则将端口删除 } } /** * 这个方法发送给所有的端口利用了foreach语句 */ public void write(){ OutputStream os; try { for (Socket socket : sockets) { //写到所有的端口 os = socket.getOutputStream(); //创建一个输出流 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));//创建一个有输出缓冲区的输出字符流 String words=textArea.getText(); //从文本框中得到文本放入words中 bw.write(words+"\n"); //将得到的文本写入包中发送出去 bw.flush(); //冲刷 } textArea.setText(""); //清空文本 } catch (IOException e) { e.printStackTrace(); } } } package com.baidu.imSwing; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.DefaultListModel; import javax.swing.JButton; import java.awt.event.ActionListener; 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 java.net.Socket; import java.net.UnknownHostException; import java.awt.event.ActionEvent; import javax.swing.JTextArea; import javax.swing.JList; /** * 这个函数的作用是 * @author Administrator * */ public class MyClient extends JFrame { private JPanel contentPane; private Socket socket; private DefaultListModel<String> modle; private JTextArea textArea; private JList list; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MyClient frame = new MyClient(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public MyClient() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 558); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JButton btnNewButton = new JButton("发送"); btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { write(); //调用write()方法,点击一次按钮就发送一次 } }); btnNewButton.setBounds(311, 458, 113, 52); contentPane.add(btnNewButton); /** * 文本输入区,可以从调用textArea.getText()方法得到当前输入的文本 */ textArea= new JTextArea(); textArea.setBounds(21, 458, 260, 52); contentPane.add(textArea); /** * 创建显示列表并建立维护列表的DefaultListModel的模型 */ list = new JList();//显示对象列表并且允许用户选择一个或多个项的组件。单独的模型 ListModel或者DefaultListModel维护列表的内容 list.setBounds(21, 44, 260, 386); modle=new DefaultListModel<>(); list.setModel(modle); contentPane.add(list); JButton btnNewButton_1 = new JButton("连接服务器"); btnNewButton_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { System.out.println("客户端启动"); socket=new Socket("192.168.0.113", 8080); //创建一个流套接字并将其连接到指定 IP 地址的指定端口号 Thread myRead=new Thread(new MyClientRead(MyClient.this));//创建新的线程对象,作用是接收发送过来的数据 myRead.start(); //启动线程 } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); btnNewButton_1.setBounds(311, 41, 113, 52); contentPane.add(btnNewButton_1); } /** * 从服务器上读取内容并在列表上显示 */ public void read(){ try { InputStream is=socket.getInputStream(); //创建以个输入流 BufferedReader br=new BufferedReader(new InputStreamReader(is));//创建一个输入缓冲区域 String line=br.readLine(); //读一行文本,放到字符line中 modle.addElement("服务器说"+line); //将line放入modle中即对话列表中 System.out.println(line); //输出文本line } catch (IOException e) { e.printStackTrace(); } } /** * 向服务器发送内容并在列表上显示 */ public void write(){ OutputStream os; try { os = socket.getOutputStream(); //构建一个输出流 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));//创建一个输出缓冲区域 String words=textArea.getText(); //从输入文本框中得到文本放入words中 bw.write(words+"\n"); //将words写入包中发送 modle.addElement("客户端说"+words); //将words放入modle中即对话列表中 textArea.setText(""); //清空文字 bw.flush(); //冲刷 } catch (IOException e) { e.printStackTrace(); } } } package com.baidu.imSwing; import java.net.Socket; public class MyServerRead implements Runnable{ private Socket socket; private MyServer server; //创建类型为MyServer的属性 public MyServerRead(MyServer server,Socket socket) { this.server=server; this.socket=socket; } @Override public void run() { while(true){ server.read(socket); //调用read方法读取端口中的内容 } } } package com.baidu.imSwing; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.DefaultListModel; import javax.swing.JButton; import java.awt.event.ActionListener; 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 java.net.Socket; import java.net.UnknownHostException; import java.awt.event.ActionEvent; import javax.swing.JTextArea; import javax.swing.JList; /** * 这个函数的作用是 * @author Administrator * */ public class MyClient extends JFrame { private JPanel contentPane; private Socket socket; private DefaultListModel<String> modle; private JTextArea textArea; private JList list; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MyClient frame = new MyClient(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public MyClient() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 558); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JButton btnNewButton = new JButton("发送"); btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { write(); //调用write()方法,点击一次按钮就发送一次 } }); btnNewButton.setBounds(311, 458, 113, 52); contentPane.add(btnNewButton); /** * 文本输入区,可以从调用textArea.getText()方法得到当前输入的文本 */ textArea= new JTextArea(); textArea.setBounds(21, 458, 260, 52); contentPane.add(textArea); /** * 创建显示列表并建立维护列表的DefaultListModel的模型 */ list = new JList();//显示对象列表并且允许用户选择一个或多个项的组件。单独的模型 ListModel或者DefaultListModel维护列表的内容 list.setBounds(21, 44, 260, 386); modle=new DefaultListModel<>(); list.setModel(modle); contentPane.add(list); JButton btnNewButton_1 = new JButton("连接服务器"); btnNewButton_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { System.out.println("客户端启动"); socket=new Socket("192.168.0.113", 8080); //创建一个流套接字并将其连接到指定 IP 地址的指定端口号 Thread myRead=new Thread(new MyClientRead(MyClient.this));//创建新的线程对象,作用是接收发送过来的数据 myRead.start(); //启动线程 } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); btnNewButton_1.setBounds(311, 41, 113, 52); contentPane.add(btnNewButton_1); } /** * 从服务器上读取内容并在列表上显示 */ public void read(){ try { InputStream is=socket.getInputStream(); //创建以个输入流 BufferedReader br=new BufferedReader(new InputStreamReader(is));//创建一个输入缓冲区域 String line=br.readLine(); //读一行文本,放到字符line中 modle.addElement("服务器说"+line); //将line放入modle中即对话列表中 System.out.println(line); //输出文本line } catch (IOException e) { e.printStackTrace(); } } /** * 向服务器发送内容并在列表上显示 */ public void write(){ OutputStream os; try { os = socket.getOutputStream(); //构建一个输出流 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));//创建一个输出缓冲区域 String words=textArea.getText(); //从输入文本框中得到文本放入words中 bw.write(words+"\n"); //将words写入包中发送 modle.addElement("客户端说"+words); //将words放入modle中即对话列表中 textArea.setText(""); //清空文字 bw.flush(); //冲刷 } catch (IOException e) { e.printStackTrace(); } } }
相关文章推荐
- hive优化四
- hdu 5068
- Dev GridView RowCellClick活动MouseDown事件
- hdu 5068 分类: hdu 2015-08-07 18:07 7人阅读 评论(0) 收藏
- 如何抓微信的请求
- KMP中求解next值的模板
- 在Linux系统中查看进程及杀死僵尸进程的方法
- 事务隔离级别
- QQ表情
- linux 同步时间 调试core内核
- C#实现清除IE浏览器缓存的方法
- 数字旋转方阵
- 报错:require_once cannot allocate memory----php,以前自己弄的稍微有点特殊的开发环境
- 关于Entity Framework采用DB First模式创建后的实体批量修改相关属性技巧
- 解决安卓TextView高度和textSize大小不一致问题
- 安装phpstorm对yii的支持(YiiStorm)
- osg 反走样学习
- 我的CSDN第一天
- 233 - Number of Digit One
- 一张图记住Linux系统常用诊断工具