服务器端程序基本结构
public class Server extends JFrame implements Runnable{
public Server(){
//服务器端打开端口
//服务端开启线程,接受客户端连接
} public void run(){
//不断接受客户端连接
while(true){
//接收客户端连接
//开一个聊天线程给这个客户端
//将该聊天线程对象添加进集合
//聊天线程启动
}
}
/*聊天线程类,每连接上一个客户端,就为它开一个聊天线程*/
class ChatThread extends Thread{
//负责读取相应 SocketConnection 的信息
public void run(){
while(true){
//读取客户端发来的信息
//将该信息发送给所有其他客户端
}
}
}
}
具体代码
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import javax.swing.JFrame;
public class Server extends JFrame implements Runnable {
private Socket s = null;
private ServerSocket ss = null;
private ArrayList clients = new ArrayList();// 保存客户端的线程
public Server() throws Exception {
this.setTitle("服务器端");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBackground(Color.yellow);
this.setSize(400, 600);
this.setVisible(true);
ss = new ServerSocket(9999);// 服务器端开辟端口,接受连接
new Thread(this).start();// 接受客户连接的死循环开始运行
}
public void run() {
try {
while (true) {
s = ss.accept();
/*
* s 就是当前的连接对应的 Socket
* 对应一个客户端 该客户端随时可能发信息过来
* 必须要接收 另外开辟一个线程,专门为这个 s 服务
* 负责接受信息
*/
ChatThread ct = new ChatThread(s);
clients.add(ct);
ct.start();
}
} catch (Exception ex) {}
}
class ChatThread extends Thread {// 为某个 Socket 负责接受信息
private Socket s = null;
private BufferedReader br = null;
public PrintStream ps = null;
public ChatThread(Socket s) throws Exception {
this.s = s;
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
ps = new PrintStream(s.getOutputStream());
}
public void run() {
try {
while (true) {
String str = br.readLine();// 读取该 Socket 传来的信息
sendMessage(str); //将 str 转发给所有客户端
}
} catch (Exception ex) {}
}
}
public void sendMessage(String msg) {// 将信息发给所有客户端
for (int i = 0; i < clients.size(); i++) {
ChatThread ct = (ChatThread) clients.get(i);
// 向 ct 内的 Socket 内写 msg
ct.ps.println(msg);
}
}
public static void main(String[] args) throws Exception {
Server server = new Server();
}
}
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.Socket;
import javax.swing.*;
public class Client extends JFrame implements ActionListener, Runnable {
private JTextArea taMsg = new JTextArea("以下是聊天记录\n");
private JTextField tfMsg = new JTextField();
private Socket s = null;
private String nickName = null;
public Client() {
this.setTitle("客户端");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(taMsg, BorderLayout.CENTER);
tfMsg.setBackground(Color.yellow);
this.add(tfMsg, BorderLayout.SOUTH);
tfMsg.addActionListener(this);
this.setSize(400, 800);
this.setVisible(true);
nickName = JOptionPane.showInputDialog("输入昵称");
try {
s = new Socket("127.0.0.1", 9999);
JOptionPane.showMessageDialog(this, "连接成功");
this.setTitle("客户端:" + nickName);
new Thread(this).start();
} catch (Exception ex) {
}
}
public void run() {
try {
while (true) {
InputStream is = s.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = br.readLine();// 读
taMsg.append(str + "\n");// 添加内容
}
} catch (Exception ex) {
}
}
public void actionPerformed(ActionEvent e) {
try {
OutputStream os = s.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println(nickName + "说:" + tfMsg.getText());
tfMsg.setText("");
} catch (Exception ex) {
}
}
public static void main(String[] args) throws Exception {
Client client = new Client();
}
}
网友评论