您的位置:首页 > 其它

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();
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: