转载:https://blog.csdn.net/zzq19860626/article/details/10220251
//服务器端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import org.apache.commons.logging.*;
public class SocketServer {
private ServerSocket serverSocket;
private HashSet<Socket> allSocket;
private static final Log LOG = LogFactory.getLog(SocketServer.class);
public SocketServer() {
try {
serverSocket=new ServerSocket(8080);
allSocket=new HashSet<Socket>();
}catch (IOException e) {
e.printStackTrace();
}
}
private void startService() throws IOException {
while(true) {
LOG.info("服务器成功启动,等待客户端相应.....");
Socket s=serverSocket.accept();
LOG.info(new Date()+" ip:"+s.getLocalAddress()+" "+"登入了聊天室!");
allSocket.add(s);
new ChatRoomServerThread(s).start();
}
}
class ChatRoomServerThread extends Thread{
private Socket socket;
public ChatRoomServerThread(Socket s) {
this.socket=s;
}
public void run(){
/**
* 得到s的输入流,并包装成BufferedReader
* 循环不停的从BufferedReader中读取数据。
* 每读到一行数据就将这一行数据转发给所有在线的客户端。
* 循环遍历allSockets,得到每一个socket,
* 然后得到该socket的输出流,并包装,再向输出流中写数据。
*/
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {
String str=br.readLine();
if(str.split(":").equals("%GOODBYE%")) {
allSocket.remove(socket);
sendMessageToAllClient(str.split(":")[0]+",离开聊天室!");
LOG.info(str.split(":")[0]+",离开聊天室!");
socket.close();
break;
}
sendMessageToAllClient(str);
}
}catch (IOException e) {
e.printStackTrace();
}
}//run end!
public void sendMessageToAllClient(String str)throws IOException{
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("hh-mm-ss");
String dateStr = sf.format(date);
for(Socket temp:allSocket) {
PrintWriter pWriter=new PrintWriter(temp.getOutputStream());
pWriter.println(str+"\t["+dateStr+"]");
pWriter.flush();
}
}
}//Thread class end!
public static void main(String[] args){
try{
new SocketServer().startService();
}catch (IOException e) {
e.printStackTrace();
}
}
}
//客户端
import java.awt.BorderLayout;
import java.awt.Font;
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.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SocketClient {
private JFrame frame;
private JTextArea area;
private JLabel label;
private JTextField field;
private JButton button;
private Socket socket;
private String userName;
private BufferedReader bufferedReader;
private PrintWriter printWriter;
private static final Log log = LogFactory.getLog(SocketClient.class);
public SocketClient() {
frame=new JFrame("聊天室");
area=new JTextArea(30,60);
label=new JLabel();
field=new JTextField(30);
button=new JButton("发送");
createConnection();
init();
addEventHandler();
}
private void createConnection() {
do {
String hostName=JOptionPane.showInputDialog(frame,"请输入服务器地址:8080");
String port=JOptionPane.showInputDialog(frame,"请输入端口号:");
try {
socket=new Socket(hostName, Integer.parseInt(port));
printWriter=new PrintWriter(socket.getOutputStream());
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
}catch (IOException e) {
JOptionPane.showMessageDialog(frame, "连接参数不正确,请重新输入");
}
}while(socket==null);
}
private void init() {
field.setFont(new Font("", Font.BOLD, 20));
area.setFont(new Font("", Font.BOLD, 24));
JScrollPane jScrollPane=new JScrollPane(area);
JPanel panel=new JPanel();
panel.add(label);
panel.add(field);
panel.add(button);
frame.add(jScrollPane,BorderLayout.CENTER);
frame.add(panel, BorderLayout.SOUTH);
}
private void addEventHandler() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(field.getText().trim().equals("")) {
JOptionPane.showMessageDialog(frame, "不能发送空内容");
return;
}
printWriter.println(userName+":"+field.getText());
printWriter.flush();
field.setText("");
}
});
frame.addWindowFocusListener(new WindowAdapter() {
public void windowClosing(WindowEvent arg0) {
/**
* 弹出对话框询问是否确定退出
* 服务器发送退出请求:userName+“:%GOODBYE%”
* 等待200毫秒,再关闭socket,退出程序
*/
int op=JOptionPane.showConfirmDialog(frame, "确定离开聊天室吗?"," 确认退出",
JOptionPane.YES_NO_OPTION);
if(op==JOptionPane.YES_OPTION) {
printWriter.println(userName+":%GGODBYE%");
log.info(userName+"离开聊天室!");
printWriter.flush();
try {
Thread.sleep(200);
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
socket.close();
}catch (IOException e) {}
System.exit(0);
}
}
}
});
}
public void showMe() {
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
new Thread() {
public void run() {
while(true) {
try {
String str=bufferedReader.readLine();
area.append(str+"\n");
}catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}
public static void main(String[] args) {
new SocketClient().showMe();
}
}