📄 chatserver.java
字号:
// 例 8.5.2 ChatServer.java
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
public class ChatServer extends JPanel
{
private JPanel topPanel = new JPanel();
private JPanel buttomPanel = new JPanel();
private DefaultTableModel defaultModel;
private JTable nameTable;
private JButton exitButton;
private JList list;
private DefaultListModel listModel;
private JButton sendButton = new JButton("发送");
private JTextField sayWord = new JTextField();
// totalThread将所有的连接保存在其中,当需要时从中取出
private Vector totalThread = new Vector();
private int port = 8082;
public ChatServer()
{
this.setLayout(new GridLayout(2, 1));
}
public void init()
{
String[] columName = new String[] { "用户名称", "IP" };
String[][] tempData = new String[][] { { "", "" } };
defaultModel = new DefaultTableModel(tempData, columName);
nameTable = new JTable(defaultModel);
nameTable.setRowHeight(22);
exitButton = new JButton("StopServer");
exitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
topPanel.setLayout(new BorderLayout());
topPanel.add(new JLabel("在线用户", JLabel.LEFT), BorderLayout.NORTH);
topPanel.add(new JScrollPane(nameTable), BorderLayout.CENTER);
listModel = new DefaultListModel();
list = new JList(listModel);
JPanel temp = new JPanel(new BorderLayout());
temp.add(sayWord, BorderLayout.CENTER);
sendButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
sendData();
}
});
temp.add(sendButton, BorderLayout.EAST);
JPanel temp2 = new JPanel();
temp2.add(exitButton);
temp.add(temp2, BorderLayout.SOUTH);
buttomPanel.setLayout(new BorderLayout());
buttomPanel.add(new JScrollPane(list), BorderLayout.CENTER);
buttomPanel.add(temp, BorderLayout.SOUTH);
this.add(topPanel);
this.add(buttomPanel);
new StartServer().start();
new UpdataThread().start();
}
// StartServer启动serverSocket等待在服务器上,为每一个请求创建一个线程
class StartServer extends Thread
{
public void run()
{
try
{
ServerSocket serverSocket = new ServerSocket(port);
while (true)
{
try
{
Socket socket = serverSocket.accept();
AcceptThread acceptThread = new AcceptThread(socket);
acceptThread.start();
totalThread.add(acceptThread);
} catch (IOException ex2) {
throw ex2;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void addWord(String word)
{
listModel.add(0, word);
}
// sendData()用于将服务器的发言发送给每一个客户端,具体怎么发送由//sendWordToEveryone来完成
private void sendData()
{
String temp = "服务器说:" + sayWord.getText().trim();
sendWordToEveryone(temp.getBytes());
addWord(temp);
}
// UpdataThread每隔6000毫秒检查在线用户并将信息显示在表格中
class UpdataThread extends Thread
{
public void run()
{
while (true)
{
String[] columName = new String[] { "用户名称", "IP" };
String[][] tempData = new String[][] {};
defaultModel = new DefaultTableModel(tempData, columName);
AcceptThread tempThread = null;
Object tempObject = null;
Enumeration enum = totalThread.elements();
while (enum.hasMoreElements())
{
tempObject = enum.nextElement();
if (tempObject != null)
{
tempThread = (AcceptThread) tempObject;
if (tempThread.isAlive())
defaultModel.addRow(new String[] {
tempThread.getUserName(),
tempThread.getUserIP() });
else
tempObject = null;
}
//我们创建了新的DefaultTableModel,调用JTable 的setModel
//方法后,JTable将显示这个DefaultTableModel的内容
nameTable.setModel(defaultModel);
}
try
{
sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
JFrame mf = new JFrame("Chat Server");
ChatServer server = new ChatServer();
mf.getContentPane().add(server);
mf.setLocation(150, 0);
mf.setSize(450, 450);
mf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
server.init();
mf.setVisible(true);
}
//serverSocket为每一个客户请求都会生成一个新的AcceptThread线程
class AcceptThread extends Thread
{
Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
String name = "DefaultName";
String ip;
boolean flag = true;
BufferedInputStream bis;
BufferedOutputStream bos;
byte[] bytes;
public AcceptThread(Socket socket)
{
this.socket = socket;
ip = socket.getInetAddress().getHostAddress();
System.out.println(ip);
try
{
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
bos = new BufferedOutputStream(outputStream, 1024);
} catch (IOException e) {
e.printStackTrace();
if (socket != null)
{
try
{
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
flag = false;
}
}
public void run()
{
bis = new BufferedInputStream(inputStream, 1024);
while (flag)
{
try
{
bytes = new byte[1024];
bis.read(bytes);
String tempS = new String(bytes);
tempS = tempS.trim();
name = tempS.substring(0, tempS.indexOf("说"));
addWord(tempS);
sendWordToEveryone(bytes);
} catch (IOException e) {
e.printStackTrace();
flag = false;
}
}
}
//AcceptThread用sendWord来向和自己建立专线连接的客户发送数据
public void sendWord(byte[] bytes)
{
try
{
bos.write(bytes);
bos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
// getUserName用于返回当前客户端的名称
public String getUserName()
{
return name;
}
// getUserName用于返回当前客户端的IP地址
public String getUserIP()
{
return ip;
}
}
// sendWordToEveryone从totalThread中提取每一个AcceptThread并向活着的
//线程发送数据
private void sendWordToEveryone(byte[] bytes)
{
Enumeration enum = totalThread.elements();
while (enum.hasMoreElements())
{
Object tempObject = enum.nextElement();
if (tempObject != null)
{
AcceptThread tempThread = (AcceptThread) tempObject;
if (tempThread.isAlive())
{
tempThread.sendWord(bytes);
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -