1.客户端类
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Client extends JFrame{
public ClientThraed ct;
private JTextArea jta;
public static void main(String[] args) {
Client client=new Client();
client.Init();
client.Dialog();
}
private void Dialog() {
JDialog jd=new JDialog(this, "登录", true);
jd.setSize(250, 200);
jd.setLocationRelativeTo(null);
jd.setLayout(new FlowLayout());
JLabel jl1=new JLabel("IP 地址");
JLabel jl2=new JLabel("端口号");
JLabel jl3=new JLabel("昵称");
JTextField jtf1=new JTextField(15);
JTextField jtf2=new JTextField(15);
JTextField jtf3=new JTextField(15);
jtf1.setText("127.0.0.1");
jtf2.setText("8888");
jtf3.setText("你好");
JButton jbt=new JButton("链接");
jbt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int port=Integer.parseInt(jtf2.getText());
try {
ct=new ClientThraed(jtf1.getText(),port,jtf3.getText(),Client.this);
ct.start();
} catch (IOException e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(Client.this, "连接失败");
}
jd.dispose();
}
});
jd.add(jl1);
jd.add(jtf1);
jd.add(jl2);
jd.add(jtf2);
jd.add(jl3);
jd.add(jtf3);
jd.add(jbt);
jd.setVisible(true);
}
private void Init() {
setSize(500, 400);
jta = new JTextArea(16,36);
JScrollPane jsp=new JScrollPane(jta);
JTextField jtf=new JTextField(28);
JButton jbt=new JButton("发送");
jbt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
ct.sendMessage(jtf.getText());
jtf.setText("");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
add(jsp);
add(jtf);
add(jbt);
setLayout(new FlowLayout());
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public void showMessage(String readLine) {
jta.append(readLine+"\r\n");
}
}
这个客户端类主要实现客户端的界面和添加收到的消息在面板上,以及调用客户端线程来收发消息,客户端的线程代码如下:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientThraed extends Thread{
BufferedReader br;
BufferedWriter bw;
Client client;
public ClientThraed(String ip, int port, String name, Client client) throws UnknownHostException, IOException {
Socket socket=new Socket(ip,port);
bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.client=client;
}
public void sendMessage(String text) throws IOException {
bw.write(text);
bw.newLine();
bw.flush();
}
@Override
public void run() {
while(true)
{
try {
client.showMessage(br.readLine()+"\r\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
以上为客户端的代码部分
2. 服务器类
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Sever extends JFrame{
public static void main(String[] args) {
Sever sever=new Sever();
sever.Init();
}
private JButton jbt;
private JTextField jtf;
private JTextArea jta;
private JTable jt;
private Vector<Vector<String>> vectorData;
List <SeverThread> sts=new ArrayList<SeverThread>();
private void add() {
JLabel jl1=new JLabel("端口号");
JLabel jl2=new JLabel("在线用户");
jtf=new JTextField(10);
jtf.setText("8888");
jbt=new JButton("服务端");
//表头
Vector<String> vector=new Vector<String>();
vector.add("IP地址");
vector.add("昵称");
vector.add("登录时间");
//数据
vectorData=new Vector< Vector<String>>();
jt=new JTable(vectorData, vector);
JScrollPane jsp=new JScrollPane(jt);
//聊天面版
jta=new JTextArea(10,10);
JScrollPane jsp1=new JScrollPane(jta);
jl2.setBounds(20,10,60,30);
add(jl2);
jl1.setBounds(230,10,60,30);
add(jl1);
jtf.setBounds(280, 14,100,20);
add(jtf);
jbt.setBounds(400, 14,80,20);
add(jbt);
jsp.setBounds(20,50,200, 300);
add(jsp);
jsp1.setBounds(250, 50, 200, 300);
add(jsp1);
}
private void addListener() {
jbt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Thread()
{
public void run() {
try {
ServerSocket ss=new ServerSocket(Integer.parseInt(jtf.getText()));
jbt.setText("关闭服务");
while(true)
{
Socket socket=ss.accept();
SeverThread st=new SeverThread(socket,Sever.this,sts);
sts.add(st);
st.start();
}
} catch (NumberFormatException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
});
}
public void addUser(Vector<String> vector) {
vectorData.add(vector);
jt.updateUI();
}
private void Init() {
setSize(500, 400);
setLayout(null);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add();
addListener();
setVisible(true);
}
public void ShowMessage(String string) {
jta.append(string+"\r\n");
}
}
以上的服务器类跟客户端类很相似,主要提供服务器的界面,以及开启服务端线程的功能,以下为服程的代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Vector;
public class SeverThread extends Thread{
BufferedWriter bw;
BufferedReader br;
Sever sever;
List<SeverThread> sts;
String name;
public SeverThread(Socket socket, Sever sever, List<SeverThread> sts) throws IOException {
bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.sever=sever;
this.sts=sts;
name=br.readLine();
Vector<String> vector=new Vector<String>();
vector.add(socket.getInetAddress().toString());
vector.add(name);
String format = "hh:mm:ss";
SimpleDateFormat sdf=new SimpleDateFormat(format);
String format2 = sdf.format(new Date(System.currentTimeMillis()));
vector.add(format2);
sever.addUser(vector);
sendMessageToAll("系统消息:用户" + name + "已经进入聊天室!");
sever.ShowMessage("系统消息:用户" + name + "已经进入聊天室!");
}
private void sendMessageToAll(String string) {
for (SeverThread severThread : sts) {
severThread.sendMessage(string);
}
}
private void sendMessage(String string) {
try {
bw.write(string);
bw.newLine();
bw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
while(true)
{
String readLine;
try {
readLine = br.readLine();
String format = "hh:mm:ss";
SimpleDateFormat sdf=new SimpleDateFormat(format);
String format2 = sdf.format(new Date(System.currentTimeMillis()));
sendMessageToAll(name +"("+format2+")");
sendMessageToAll(readLine);
sever.ShowMessage(name +"("+format2+")"+readLine);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
以上代码可以实现客户端的聊天,至于多人聊天和私聊的可以在此基础上加上各种功能,代码实现的界面和效果如下图:
服务器界面:
客户端1界面:
客户端2界面:
以上即为java socket简单聊天系统的全部内容。