时间:2023-02-16 09:33:10 | 栏目:JAVA代码 | 点击:次
本文实例为大家分享了java+socket实现简易局域网聊天室的具体代码,供大家参考,具体内容如下
ServerFrame.java
package com.eze.chatroom.server; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.JLabel; import java.awt.Color; import java.awt.Font; import javax.swing.JTextField; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JScrollPane; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class ServerFrame extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel contentPane; private JTextField txtPort; private JLabel lblOnlineCount; private JTextArea txtAreaInfo; private Server server; private JTextArea txtAreaPals; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ServerFrame frame = new ServerFrame(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public ServerFrame() { this.setTitle("server"); this.setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 658, 428); contentPane = new JPanel(); contentPane.setForeground(Color.DARK_GRAY); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JLabel lblPort = new JLabel("port :"); lblPort.setFont(new Font("宋体", Font.PLAIN, 18)); lblPort.setBounds(14, 13, 72, 31); contentPane.add(lblPort); txtPort = new JTextField(); txtPort.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { int c = e.getKeyChar(); if(!(c > KeyEvent.VK_0 && c < KeyEvent.VK_9)){ e.consume(); } } }); txtPort.setFont(new Font("宋体", Font.PLAIN, 20)); txtPort.setBounds(89, 18, 138, 24); contentPane.add(txtPort); txtPort.setColumns(10); JScrollPane scrollPane = new JScrollPane(); scrollPane.setBounds(245, 103, 378, 272); contentPane.add(scrollPane); txtAreaInfo = new JTextArea(); scrollPane.setViewportView(txtAreaInfo); txtAreaInfo.setFont(new Font("Monospaced", Font.PLAIN, 20)); JButton btnChange = new JButton("start"); btnChange.addMouseListener(new MouseAdapter() { private boolean flag = true; @Override public void mouseClicked(MouseEvent e) { String portStr = txtPort.getText().trim(); boolean isvalid = false; int port = 9999; if(!(portStr.startsWith("0") || portStr.equals(""))){ port = Integer.valueOf(portStr); if(port >= 1024 && port <= 65535) isvalid = true; } if(!isvalid){ JOptionPane.showMessageDialog(ServerFrame.this, "invalid port that is expected to put into the range of 1024~65535"); return; } if(flag){ btnChange.setText("stop"); txtAreaInfo.append("server started\n"); flag = false; ServerFrame.this.server = new Server(ServerFrame.this, ServerFrame.this.getTitle(), port); Thread thdServer = new Thread(new Runnable() { @Override public void run() { ServerFrame.this.server.start(); } }); thdServer.start(); }else{ btnChange.setText("start"); ServerFrame.this.server.stop(); txtAreaInfo.append("server stopped\n"); flag = true; } } }); btnChange.setFont(new Font("宋体", Font.PLAIN, 19)); btnChange.setBackground(new Color(240, 255, 240)); btnChange.setForeground(new Color(178, 34, 34)); btnChange.setBounds(270, 17, 113, 27); contentPane.add(btnChange); JLabel lblPalsOnline = new JLabel("pals online:"); lblPalsOnline.setBounds(18, 73, 113, 18); contentPane.add(lblPalsOnline); JLabel lblLogInfo = new JLabel("log info"); lblLogInfo.setBounds(285, 73, 72, 18); contentPane.add(lblLogInfo); lblOnlineCount = new JLabel("0"); lblOnlineCount.setBounds(123, 75, 72, 18); contentPane.add(lblOnlineCount); JScrollPane scrollPane_1 = new JScrollPane(); scrollPane_1.setBounds(14, 111, 213, 264); contentPane.add(scrollPane_1); txtAreaPals = new JTextArea(); scrollPane_1.setViewportView(txtAreaPals); } public JLabel getLblOnlineCount() { return lblOnlineCount; } public JTextArea getTxtAreaPals() { return txtAreaPals; } public JTextArea getTxtAreaInfo() { return txtAreaInfo; } }
Server.java
package com.eze.chatroom.server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JTextArea; public class Server { private ServerSocket server; private List<Socket> clients; private Map<String, String> pals; @SuppressWarnings("unused") private String name; private int port; private ServerFrame frame; public Server(ServerFrame frame, String name, int port){ this.frame = frame; this.name = name; this.port = port; this.clients = new ArrayList<>(); this.pals = new HashMap<>(); } public void start(){ try { this.server = new ServerSocket(port); System.out.println("server start at port "+port); while(true){ Socket client = server.accept(); Thread thdHandConn = new Thread(new HandleConnection(client, clients, pals, frame)); thdHandConn.start(); } }catch(SocketException e){ System.out.println("server stop"); }catch (IOException e) { e.printStackTrace(); } } public void stop(){ try { for(Socket sock : clients){ sock.close(); } server.close(); } catch (IOException e) { e.printStackTrace(); } } public static void autoRoll(JTextArea area){ area.setCaretPosition(area.getText().length()); } }
HandleConnnection.java
package com.eze.chatroom.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; public class HandleConnection implements Runnable { private Socket client; private List<Socket> clients; private Map<String, String> pals; private ServerFrame frame; public HandleConnection(Socket client, List<Socket> clients, Map<String, String> pals, ServerFrame frame){ this.client = client; this.clients = clients; this.pals = pals; this.frame = frame; } @Override public void run() { String username = null; SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { DataInputStream dataInput = new DataInputStream(client.getInputStream()); DataOutputStream dataOutput = new DataOutputStream(client.getOutputStream()); String totalFirst = dataInput.readUTF(); username = totalFirst.split("_")[0]; if(username.equals("")){ dataOutput.writeUTF("no"); client.close(); return; } dataOutput.writeUTF("ok"); String hello = formatDate.format(new Date())+"\n"+client.getRemoteSocketAddress().toString()+username+" join romm\n"; frame.getTxtAreaInfo().append(hello); Server.autoRoll(frame.getTxtAreaInfo()); this.forwardMsg(hello); clients.add(client); pals.put(client.getRemoteSocketAddress().toString(), username); this.updatePalsList(); while(true){ String word = dataInput.readUTF(); String date = formatDate.format(new Date()); String msg = date+" "+username+"\n"+word; frame.getTxtAreaInfo().append(msg+"\n"); Server.autoRoll(frame.getTxtAreaInfo()); this.forwardMsg(msg); } }catch (SocketException e) { clients.remove(client); pals.remove(client.getRemoteSocketAddress().toString(), username); this.updatePalsList(); String leaveMsg = formatDate.format(new Date())+"\n"+username+" leaved room\n"; this.frame.getTxtAreaInfo().append(leaveMsg); Server.autoRoll(frame.getTxtAreaInfo()); this.forwardMsg(leaveMsg); }catch (IOException e) { e.printStackTrace(); } } protected void updatePalsList(){ this.frame.getLblOnlineCount().setText(String.valueOf(clients.size())); this.frame.getTxtAreaPals().setText(""); for(Map.Entry<String, String> entry : pals.entrySet()){ this.frame.getTxtAreaPals().append(entry.getKey()+" "+entry.getValue()+"\n"); } } protected void forwardMsg(String msg){ try { for(Socket sock : clients){ if(sock != client){ DataOutputStream dataOutput = new DataOutputStream(sock.getOutputStream()); dataOutput.writeUTF(msg); } } } catch (IOException e) { e.printStackTrace(); } } }
ClientLoginViewer.java
package com.eze.chatroom.client; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.JButton; import java.awt.Font; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class ClientLoginViewer extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel contentPane; private ClientWin win; private JTextField txtUsername; private JTextField txtServer; private JLabel lblPort; private JTextField txtPort; private Client client; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ClientLoginViewer frame = new ClientLoginViewer(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public ClientLoginViewer() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 603, 366); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JLabel lblNewLabel = new JLabel("username:"); lblNewLabel.setFont(new Font("宋体", Font.PLAIN, 20)); lblNewLabel.setBounds(71, 41, 113, 18); contentPane.add(lblNewLabel); txtUsername = new JTextField(); txtUsername.setText("admin"); txtUsername.setBounds(209, 38, 235, 24); contentPane.add(txtUsername); txtUsername.setColumns(10); JLabel lblServer = new JLabel("server:"); lblServer.setFont(new Font("宋体", Font.PLAIN, 20)); lblServer.setBounds(71, 93, 90, 18); contentPane.add(lblServer); txtServer = new JTextField(); txtServer.setText("localhost"); txtServer.setColumns(10); txtServer.setBounds(209, 92, 235, 24); contentPane.add(txtServer); lblPort = new JLabel("port:"); lblPort.setFont(new Font("宋体", Font.PLAIN, 20)); lblPort.setBounds(71, 149, 90, 18); contentPane.add(lblPort); txtPort = new JTextField(); txtPort.setText("2222"); txtPort.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { int c = e.getKeyChar(); if(c < KeyEvent.VK_0 || c > KeyEvent.VK_9){ e.consume(); } } }); txtPort.setBounds(209, 148, 235, 24); contentPane.add(txtPort); txtPort.setColumns(10); JButton btnLogin = new JButton("login"); btnLogin.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); btnLogin.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { String username = txtUsername.getText(); String server = txtServer.getText(); String portStr = txtPort.getText(); if(!this.argsValid(username, server, portStr)){ String error = "please input valid arguments which username, password, server, port" + " are not allowed be empty and port should be in the range of 1024~65535"; JOptionPane.showMessageDialog(ClientLoginViewer.this, error); return; } client = new Client(username, server, Integer.valueOf(portStr), ClientLoginViewer.this.win); if(ClientLoginViewer.this.client.login()){ ClientLoginViewer.this.setVisible(false); ClientLoginViewer.this.win.setVisible(true); win.setClient(client); }else{ JOptionPane.showMessageDialog(ClientLoginViewer.this, "login falied"); } } protected boolean argsValid(String username, String server, String portStr){ if(username.equals("") || server.equals("") || portStr.equals("")) return false; int port = Integer.valueOf(portStr); if(port < 1024 || port > 65535) return false; return true; } }); btnLogin.setFont(new Font("宋体", Font.PLAIN, 20)); btnLogin.setBounds(213, 222, 113, 27); contentPane.add(btnLogin); this.initOther(); } protected void initOther(){ this.win = new ClientWin(); this.setResizable(false); } }
ClientWin.java
package com.eze.chatroom.client; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import com.eze.chatroom.server.Server; import javax.swing.JTextField; import javax.swing.JScrollPane; import javax.swing.JButton; import java.awt.Font; import javax.swing.JTextArea; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.DataOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class ClientWin extends JFrame { /** * */ private static final long serialVersionUID = 1L; private JPanel contentPane; private JTextField txtSendMsg; private JTextArea txtAreaShowMsg; @SuppressWarnings("unused") private Client client; private DataOutputStream dataOutput; private JScrollPane scrollPane; /** * Create the frame. */ public ClientWin() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 631, 467); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); scrollPane = new JScrollPane(); scrollPane.setBounds(7, 7, 595, 351); contentPane.add(scrollPane); txtAreaShowMsg = new JTextArea(); txtAreaShowMsg.setFont(new Font("Monospaced", Font.PLAIN, 20)); scrollPane.setViewportView(txtAreaShowMsg); txtSendMsg = new JTextField(); txtSendMsg.setBounds(14, 371, 265, 41); txtSendMsg.setFont(new Font("宋体", Font.PLAIN, 20)); contentPane.add(txtSendMsg); txtSendMsg.setColumns(10); JButton btnPost = new JButton("post"); btnPost.addMouseListener(new MouseAdapter() { private SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public void mouseClicked(MouseEvent e) { String sendMsg = txtSendMsg.getText(); if(!sendMsg.equals("")){ try { String date = dateFormate.format(new Date()); dataOutput.writeUTF(sendMsg); ClientWin.this.getTxtAreaShowMsg().append(date+" you\n"+sendMsg+"\n"); Server.autoRoll(ClientWin.this.getTxtAreaShowMsg()); ClientWin.this.txtSendMsg.setText(""); } catch (IOException e1) { e1.printStackTrace(); } } } }); btnPost.setBounds(377, 378, 113, 27); btnPost.setFont(new Font("宋体", Font.PLAIN, 20)); contentPane.add(btnPost); this.initOther(); } protected void initOther(){ this.setResizable(false); } public void setClient(Client client) { this.client = client; try { this.dataOutput = new DataOutputStream(client.getClient().getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } public JTextArea getTxtAreaShowMsg() { return txtAreaShowMsg; } public void setTxtSendMsg(JTextField txtSendMsg) { this.txtSendMsg = txtSendMsg; } }
Client.java
package com.eze.chatroom.client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JOptionPane; public class Client { private Socket client; private String username; private String server; private int port; private ClientWin win; public Client(String username, String server, int port, ClientWin win){ this.username = username; this.server = server; this.port = port; this.win = win; } public boolean login(){ try { client = new Socket(server, port); DataInputStream dataInput = new DataInputStream(client.getInputStream()); DataOutputStream dataOutput = new DataOutputStream(client.getOutputStream()); dataOutput.writeUTF(username+"_"); String ret = dataInput.readUTF(); if(ret.contains("ok")){ Thread thdReader = new Thread(new ClientReader(client, win)); thdReader.start(); return true; } } catch (UnknownHostException e) { e.printStackTrace(); JOptionPane.showMessageDialog(win, "unknown host"); } catch (IOException e) { e.printStackTrace(); } return false; } public Socket getClient() { return client; } }
ClientReader.java
package com.eze.chatroom.client; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; import javax.swing.JOptionPane; import com.eze.chatroom.server.Server; public class ClientReader implements Runnable { private ClientWin win; private Socket client; public ClientReader(Socket client ,ClientWin win){ this.client = client; this.win = win; } @Override public void run() { this.doHand(); } protected void doHand(){ try { DataInputStream dataInput = new DataInputStream(client.getInputStream()); while(true){ String msg = dataInput.readUTF(); win.getTxtAreaShowMsg().append(msg+"\n"); Server.autoRoll(win.getTxtAreaShowMsg()); } } catch (IOException e) { //e.printStackTrace(); try { client.close(); } catch (IOException e1) { e1.printStackTrace(); } System.out.println("client disconnected"); JOptionPane.showMessageDialog(win, "you have been disconnected"); } } }
运行效果