以前写的一个简易聊天程序(示意性的,很简陋!),利用socket分别实现服务端、客户端。
启动服务端,在两个客户端中点击“建立连接”后,即可进行对话。
主要代码如下:
服务端
public class Server {
public Server() {
initServer();
}
private void initServer() {
try {
serverSocket = new ServerSocket(port, 2);
// serverSocket.setSoTimeout(10000); //设置等待客户连接的超时时间为10s
System.out.println("服务器启动...");
} catch (IOException e) {
e.printStackTrace();
}
}
public void serve() {
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();// 如果服务器未关闭,则一直等候客户端的连接
Thread workThread = new Thread(new ServiceLink(socket));
workThread.start();
sockets[n++] = socket;
} catch (IOException t) {
t.printStackTrace();
}
}
}
// 负责与单个用户进行通信的任务
class ServiceLink implements Runnable {
private Socket socket = null; // 用户通信的Socket
public ServiceLink(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader in = null;
try {
System.out.println("建立新的连接! " + socket.getInetAddress()
+ ":" + socket.getPort());
in = getReader(socket);
String tempMsg = "";
// 服务器向客户端群发公共信息
while ((tempMsg = in.readLine()) != null) {
sendMessage(tempMsg, socket);
System.out.println(tempMsg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 客户端断开与服务器的通信
try {
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException r) {
r.printStackTrace();
}
}
}
}
// 服务器把接收到的信息 群发给 所有其他用户
public void sendMessage(String m, Socket socket) {
// Socket socket = user.getSocket();
PrintWriter pw = null;
for (int i = 0; i < sockets.length; i++) {
if (sockets[i] != socket) {
try {
pw = getWriter(sockets[i]);
pw.println(m); // "Other Client:" +
} catch (Exception e) {
e.printStackTrace();
}
} else
continue;
}
}
public void closeClientLink(){
for(Socket socket : sockets){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("连接已断开!");
}
// 获取输入流
public static BufferedReader getReader(Socket socket) { // User user
// Socket socket = user.getSocket();
InputStream socketIn = null;
try {
socketIn = socket.getInputStream();
} catch (IOException t) {
t.printStackTrace();
}
return new BufferedReader(new InputStreamReader(socketIn));
}
// 获取输出流
public static PrintWriter getWriter(Socket socket) {
// Socket socket = user.getSocket();
OutputStream socketOut = null;
try {
socketOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
return new PrintWriter(socketOut, true);
}
public static String hostName = "localhost"; // 127.0.0.1
public static int port = 6000;
private ServerSocket serverSocket;
private int maxLink = 2;
private Socket[] sockets = new Socket[maxLink];
private int n = 0;// 当前服务器接收到要处理的连接数
public static File fileSave = null;
public static File fileSend = null;
}
客户端
public class User1 extends JFrame {
public User1() {
setSize(600, 500);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
initComponents();
}
private void initComponents() {
setLayout(new FlowLayout());
linkButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new ClientThread().start(); // 为当前客户端与服务器的连接创建启动一个线程
}
});
unlinkButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Server().closeClientLink();
}
});
sendMessage.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
sentence = sendMessage.getText();
sendMessage.setText("");
// sendMessage.setCaretPosition(0);
time = Util.getTime();
pw.println(getUserName() + " " + time); // socket输出流
pw.println(" " + sentence + "/n");
message.append(getUserName() + " " + time + "/n"); // JTextArea
message.append(" " + sentence + "/n/n");
}
}
});
func.setLayout(new GridLayout(1, 2));
func.add(linkButton);
func.add(unlinkButton);
message.setLineWrap(true);
sendMessage.setLineWrap(true);
message.setWrapStyleWord(true);
sendMessage.setWrapStyleWord(true);
message.setEditable(false); // message为消息对话框,不可修改
t1 = new JScrollPane(message);
t2 = new JScrollPane(sendMessage);
splitText = new JSplitPane(JSplitPane.VERTICAL_SPLIT, t1, t2);
splitText.setDividerLocation(300);
split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, func, splitText);
setContentPane(split); // 设置内容面板
validate();
}
// 处理客户端与服务器通信的线程类
class ClientThread extends Thread {
public ClientThread() {
try {
socket = new Socket(Server.hostName, port); // Server.
in = Server.getReader(socket);
pw = Server.getWriter(socket);
} catch (Exception r) {
JOptionPane.showMessageDialog(null, "连接服务器失败!", "Error",
JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
}
public void run() {
try {
while ((sentence = in.readLine()) != null) {
// time = getTime();
// message.append(getUserName() + " " + time + "/n");
message.append(sentence + "/n");// " " + + "/n/n"
}
} catch (IOException t) {
t.printStackTrace();
}
}
}
public String getUserName() {
return userName;
}
public void setUserName(String username) {
userName = username;
}
private JButton linkButton = new JButton("建立连接");
private JButton unlinkButton = new JButton("断开连接");
private JScrollPane t1, t2;
public static JTextArea message = new JTextArea(); // static
public static JTextArea sendMessage = new JTextArea();
private JSplitPane split;
private JSplitPane splitText;
private JPanel func = new JPanel();
private String userName;
private String time, sentence;
private int port = 6000;
int read = 0;
int bufferSize = 8192;
private static Socket socket = null;
private static BufferedReader in = null;
private static PrintWriter pw = null;
}