服务端
运行程序时要先运行服务端,同时保证服务端与客户端的端口,ip一致。
package chat;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
public class ChatServer {
ServerSocket serverSocket;
ArrayList<BufferedReader>bReaders = new ArrayList<BufferedReader>();
ArrayList<PrintWriter>pWriters = new ArrayList<PrintWriter>();
LinkedList<String>msgList = new LinkedList<String>();
public ChatServer(){
try{
serverSocket = new ServerSocket(28888);
}catch (IOException e){
e.printStackTrace();
}
new AcceptSocketThread().start();
new SendMsgToClient().start();
System.out.println("server start...");
}
// accept socket thread from client
class AcceptSocketThread extends Thread{
public void run(){
try {
while (this.isAlive()){
Socket socket = serverSocket.accept();
if (socket != null){
BufferedReader bReader = new BufferedReader(
new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)
);
bReaders.add(bReader);
new GetMsgFromClient(bReader).start();
pWriters.add(new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8)));
System.out.println("InPutStream"+bReaders.size());
System.out.println("OutPutStream"+pWriters.size());
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
class GetMsgFromClient extends Thread{
BufferedReader bReader;
public GetMsgFromClient(BufferedReader bReader){
this.bReader = bReader;
}
public void run(){
try {
while (this.isAlive()){
String strMsg = bReader.readLine();
if(strMsg != null){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String strTime = dateFormat.format(new Date());
msgList.addFirst("<=="+strTime+"==>\n"+strMsg);
}
}
}catch (SocketException se){
int index = bReaders.indexOf(bReader);
try {
bReaders.remove(index).close();
}catch (IOException e){
e.printStackTrace();
}
pWriters.remove(index).close();
System.out.println("InPutStream"+bReaders.size());
System.out.println("OutPutStream"+pWriters.size());
}catch (Exception e){
e.printStackTrace();
}
}
}
// send all message to all client
class SendMsgToClient extends Thread{
public void run(){
try {
while (this.isAlive()){
if (!msgList.isEmpty()){
String msg = msgList.removeLast();
for (int i = 0; i<pWriters.size(); i++){
pWriters.get(i).println(msg);
pWriters.get(i).flush();
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ChatServer();
}
}
运行结果:
server start...
客户端
package chat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
public class ChatClient extends JFrame {
Socket socket;
PrintWriter pWriter;
BufferedReader bReader;
JPanel panel;
JScrollPane sPane;
JTextArea txtContent;
JLabel lblName,lblSend;
JTextField txtName,txtSend;
JButton btnSend;
public ChatClient(){
super("POEM Chat");
txtContent = new JTextArea();
txtContent.setEditable(false);
sPane = new JScrollPane(txtContent);
lblName = new JLabel("Name:");
txtName = new JTextField(5);
lblSend = new JLabel("Remark:");
txtSend = new JTextField(20);
btnSend = new JButton("Send");
panel = new JPanel();
panel.add(lblName);
panel.add(txtName);
panel.add(lblSend);
panel.add(txtSend);
panel.add(btnSend);
this.add(panel, BorderLayout.SOUTH);
this.add(sPane);
this.setSize(500,300);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
try{
socket = new Socket("localhost",28888);
pWriter = new PrintWriter(new OutputStreamWriter( socket.getOutputStream(), StandardCharsets.UTF_8));
bReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
}catch (UnknownHostException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
// register listening
btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String strName = txtName.getText();
String strMsg = txtSend.getText();
if (!strMsg.equals("")){
// io send data to server
pWriter.println(strName+"Tell:"+strMsg);
pWriter.flush();
txtSend.setText("");
}
}
});
// start thread
new GetMsgFromServer().start();
}
// accept data from server
class GetMsgFromServer extends Thread{
public void run(){
try{
while (this.isAlive()){
String strMsg = bReader.readLine();
if(strMsg != null){
txtContent.append(strMsg+"\n");
}
Thread.sleep(50);
}
}catch (SocketException se){
try {
bReader.close();
}catch (IOException e){
throw new RuntimeException(e);
}
pWriter.close();
System.out.println("without sever...");
System.exit(0);
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ChatClient().setVisible(true);
}
}
运行结果 :
此时可将客户端“允许多个实例”打开