实现基于C/S模式的聊天室程序。
聊天室共分为服务器端和客户端两部分。
客户端界面包括如下部分:
(1)服务器IP设置。
(2)服务器端口设置。
(3)用户名设置。
(4)聊天记录显示。
(5)与服务器连接按钮。
(6)消息发送。
界面如下图所示
CServer.java:
package Chat;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Hashtable;
public class CServer extends Frame{
TextArea textArea = new TextArea(20, 50); //显示用户登录信息及全部在线用户所发送的信息
Socket socket = null;
Socket socket1 = null;
Hashtable hashtable = new Hashtable();
//客户端不传参数时服务器窗口标题为空
public CServer() throws HeadlessException {
super();
init();
}
//客户端传入参数作为服务器窗口标题
public CServer(String string) throws HeadlessException {
super(string);
init();
}
//向所有在服务器中的客户端进行广播
public void boradCast(String str, Socket self) {
// TODO Auto-generated method stub
Enumeration enumeration = hashtable.keys();
System.out.println("本聊天室共有"+hashtable.size()+"人");
PrintStream printStream = null;
textArea.append(str);
while (enumeration.hasMoreElements()) {
String s = (String)enumeration.nextElement();
socket1 = (Socket)hashtable.get(s);
if (socket1 != self) {
try {
printStream = new PrintStream(socket1.getOutputStream());
printStream.println(str);
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
//窗口初始化方法
public void init() {
//textArea.setEditable(false);
this.add(textArea);
this.pack();
this.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
System.exit(-1);
}
@Override
public void windowClosed(WindowEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent arg0) {
// TODO Auto-generated method stub
}
});
this.setVisible(true);
startServer();
}
//启动服务
public void startServer() {
// TODO Auto-generated method stub
try {
ServerSocket serverSocket = new ServerSocket(3333);
//启动服务,一直等待客户端请求
while (true) {
socket = serverSocket.accept();
//接受客户端请求之后,产生socket对象,交给多线程聊天服务处理
Service ser = new Service(socket);
new Thread(ser).start();
}
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
//定义内部类
class Service implements Runnable {
Socket socket = null;
String name;
public Service(Socket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
try {
BufferedReader b1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
name = b1.readLine();
hashtable.put(name, socket);
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
public Service() {
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //得到输入流,可以得到客户端输出流
boradCast(name+"进入聊天室\n", socket);
//保证不断地从客户端获得输入流,并输出到屏幕上
while (true) {
String str = "";
System.out.println("服务器"+socket.isClosed());
if ((str = br.readLine()) != null) {
boradCast(name+"说:"+str+"\n", socket);
}
//退出
if ("quit".equals(str)) {
hashtable.remove(name);
break;
}
}
br.close();
socket.close();
textArea.append("关闭连接"+name);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CServer cServer = new CServer("服务器");
}
}
CClient.java:
package Chat;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.HeadlessException;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
public class CClient extends JFrame{
TextArea textArea = new TextArea(18, 50);
TextField textField = new TextField(40);
TextField nickname = new TextField(20);
TextField address = new TextField("localhost", 10);
TextField port = new TextField("3333", 5);
Button sendBtn = new Button("发送");
Button connBtn = new Button("连接");
Panel panel1 = new Panel();
Panel panel2 = new Panel();
Socket socket = null;
PrintStream printStream = null;
public CClient() throws HeadlessException{
// TODO Auto-generated constructor stub
super();
init();
}
public CClient(String string) throws HeadlessException{
super(string);
init();
}
public void init() {
// TODO Auto-generated method stub
this.add(textArea);
panel1.add(new Label("地址"));
panel1.add(address);
panel1.add(new Label("端口号"));
panel1.add(port);
panel1.add(new Label("昵称"));
panel1.add(nickname);
panel2.add(connBtn);
panel2.add(textField);
panel2.add(sendBtn);
sendBtn.addActionListener(new MyListener());
connBtn.addActionListener(new connBtnListener());
this.add(panel1, BorderLayout.NORTH);
this.add(panel2, BorderLayout.SOUTH);
System.out.println(this.getTitle());
this.pack();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
PrintStream printStream;
try {
printStream = new PrintStream(socket.getOutputStream());
printStream.println("quit");
} catch (IOException e2) {
// TODO: handle exception
e2.printStackTrace();
}
close();
System.exit(-1);
}
});
this.setVisible(true);
connect(); //连接服务器
}
public void close() {
if (printStream != null) {
printStream.close();
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
//连接服务器
public void connect() {
try {
socket = new Socket(address.getText(), Integer.parseInt(port.getText()));
this.setTitle(nickname.getText());
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
public void recive() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String string = "";
while ((string = br.readLine()) != null) {
textArea.append(string + "\n");
}
} catch (IOException e) {
// TODO: handle exception
System.exit(-1);
}
}
//发送个人昵称到服务器
public void sendName() {
String name = nickname.getText();
PrintStream printStream;
try {
printStream = new PrintStream(socket.getOutputStream());
printStream.println(name);
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
class MyListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
try {
PrintStream printStream =new PrintStream(socket.getOutputStream());
printStream.println(textField.getText());
textArea.append("我说:"+textField.getText()+"\n");
textField.setText("");
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
class connBtnListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
connect();
sendName();
Recive r = new Recive(); //监听服务器消息
new Thread(r).start();;
}
}
class Recive implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
recive();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CClient cClient = new CClient("客户端");
}
}