Java使用socket网络编程实现多人聊天室
来源:互联网 发布:javascript弹出框原理 编辑:程序博客网 时间:2024/05/16 16:24
前言:套接字(socket)编程能够实现服务器和客户端的通信,以下通过Socket编程结合多线程实现多人聊天室。
程序展示:
界面类
1.客户端界面 ClientView.java
public class ClientView extends JFrame implements ActionListener, KeyListener, Runnable { private JTextArea textArea; private JTextField textField, tfName; private JButton btnSend, btnId; private JLabel label; private JPanel jp1, jp2; public boolean isConnect = false; private Socket socket = null; private DataInputStream inputStream = null; private DataOutputStream outputStream = null; private JScrollPane scrollPane; private static ClientView view; public JTextArea getTextArea() { return textArea; } public DataInputStream getInputStream() { return inputStream; } public DataOutputStream getOutputStream() { return outputStream; } public static void main(String[] args) { view = new ClientView(); ServiceView.clientViews.add(view); Thread thread = new Thread(view); thread.start(); } public ClientView() { initView(); try { socket = new Socket("localhost", 9090);//连接本地服务器 } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void initView() { textArea = new JTextArea(20, 20); textArea.setEditable(false); scrollPane = new JScrollPane(textArea); textField = new JTextField(15); textField.addKeyListener(this); btnSend = new JButton("发送"); btnSend.addActionListener(this); label = new JLabel("昵称:"); tfName = new JTextField(8); jp1 = new JPanel(); jp2 = new JPanel(); jp1.add(label); jp1.add(tfName); tfName.setText("用户0"); jp1.setLayout(new FlowLayout(FlowLayout.CENTER)); jp2.add(textField); jp2.add(btnSend); jp2.setLayout(new FlowLayout(FlowLayout.CENTER)); add(jp1, BorderLayout.NORTH); add(scrollPane, BorderLayout.CENTER); add(jp2, BorderLayout.SOUTH); setTitle("聊天室"); setSize(500, 500); setLocation(450, 150); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); addWindowListener(new WindowAdapter() { //窗口关闭后断开连接 @Override public void windowClosing(WindowEvent e) { try { if (socket != null) socket.close(); if (inputStream!= null) inputStream.close(); if (outputStream != null) outputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } } }); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == btnSend) { sendMsg(); } } private void sendMsg() { try { String s = textField.getText(); if (!s.equals("")) { //发送数据 textField.setText(""); textArea.append("我(" + tfName.getText() + "):\r\n" + s + "\r\n"); outputStream = new DataOutputStream(socket.getOutputStream()); outputStream.writeUTF(tfName.getText() + "#" + s); outputStream.flush(); } } catch (IOException e) { e.printStackTrace(); } } @Override public void keyPressed(KeyEvent arg0) { if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { sendMsg(); } } @Override public void keyReleased(KeyEvent arg0) { } @Override public void keyTyped(KeyEvent arg0) { } @Override public void run() { try { inputStream = new DataInputStream(socket.getInputStream()); while (true) { String[] s = inputStream.readUTF().split("#"); textArea.append(s[0] + ":\r\n" + s[1] + "\r\n"); } } catch (IOException e) { } }}
2.服务器界面 ServiceView.java
public class ServiceView extends JFrame implements ActionListener{ private JButton btnOpen, btnStop; private JLabel label; private Service service = null; public static ArrayList<ClientView> clientViews = new ArrayList<>(); private static ServiceView view; public static ServiceView getView() { return view; } public static void main(String[] args) { view = new ServiceView(); } public ServiceView() { initView(); } private void initView() { btnOpen = new JButton("打开服务器"); btnStop = new JButton("关闭服务器"); btnStop.setEnabled(false); btnOpen.addActionListener(this); btnStop.addActionListener(this); label = new JLabel("服务器停止工作"); add(label); add(btnOpen); add(btnStop); setTitle("服务器"); setLayout(new GridLayout(3, 1, 0, 10)); setSize(300, 300); setLocation(450, 150); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == btnOpen) { open(); } else { stop(); } } public void open() { //开启服务器 service = new Service(); Thread thread = new Thread(service); thread.start(); label.setText("服务器正在运行"); btnOpen.setEnabled(false); btnStop.setEnabled(true); } public void stop() { //关闭服务器 label.setText("服务器已关闭"); btnOpen.setEnabled(true); btnStop.setEnabled(false); try { synchronized (ClientMannager.sockets) { //关闭各个连接 for (ChatSocket socket : ClientMannager.sockets) { socket.getInputStream().close(); socket.getOutputStream().close(); } ClientMannager.sockets.removeAllElements(); } for (ClientView view : clientViews) { view.getInputStream().close(); view.getOutputStream().close(); } service.getServerSocket().close(); } catch (IOException e) { e.printStackTrace(); } }}
功能类
1.ChatSocket.java
/*使用socket获得数据流,达到传输数据的目的*/public class ChatSocket implements Runnable{ private Socket socket = null; private DataInputStream inputStream = null; private DataOutputStream outputStream = null; public DataInputStream getInputStream() { return inputStream; } public DataOutputStream getOutputStream() { return outputStream; } public ChatSocket(Socket socket) { this.socket = socket; try { inputStream = new DataInputStream(socket.getInputStream()); outputStream = new DataOutputStream(socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } public void send(String send) { //向客户端发送数据 try { outputStream.writeUTF(send); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { //循环读取客户端发来的数据 String accept = null; while (true) { try { accept = inputStream.readUTF(); ClientMannager.sendAll(this, accept); } catch (IOException e) { ClientMannager.sockets.remove(this); } } }}
2.ClientMannager.java
/*客户端管理器*/public class ClientMannager { private ClientMannager() { } public static Vector<ChatSocket> sockets = new Vector<>(); //向其他客户端发送数据 public static void sendAll(ChatSocket chatSocket, String send) { for (ChatSocket socket : sockets) { if (!chatSocket.equals(socket)) { socket.send(send); } } }}
3.Service.java
/*服务器端,使用线程达到循环等待连接的目的*/public class Service implements Runnable{ private ServerSocket serverSocket = null; public ServerSocket getServerSocket() { return serverSocket; } @Override public void run() { try { serverSocket = new ServerSocket(9090); //创建端口 while (true) { //循地接收客户端的连接 Socket socket = serverSocket.accept(); JOptionPane.showMessageDialog(ServiceView.getView(), "客户端连接端口", "TIP", JOptionPane.INFORMATION_MESSAGE); ChatSocket chatSocket = new ChatSocket(socket); //新客户端连接 ClientMannager.sockets.add(chatSocket); //往客户端管理器里添加客户 Thread thread = new Thread(chatSocket); //启用线程使服务器开始不断接收客户端信息 thread.start(); } } catch (IOException e) { e.printStackTrace(); System.out.println("服务器关闭"); } }}
4 0
- Java使用socket网络编程实现多人聊天室
- Java使用socket网络编程实现多人聊天室
- 使用java swing和socket编程实现简单的多人聊天室
- java网络编程,通过TCP,Socket实现多对一的局域网聊天室 .
- java网络编程,通过TCP,Socket实现多对一的局域网聊天室
- java网络编程,通过TCP,Socket实现多对一的局域网聊天室
- Java网络编程,通过TCP,Socket实现多对一的局域网聊天室
- SOCKET网络编程:Linux下实现聊天室
- Java——多人聊天室(基于TCP的网络编程——Socket)
- Java Socket网络编程--聊天室的实现(多线程实现无需等待对方响应版本)
- Java编程:Socket聊天室
- 使用Android网络编程实现简易聊天室
- 使用Android网络编程实现简易聊天室
- 使用Android网络编程实现简易聊天室
- 使用Android网络编程实现简易聊天室
- 使用Android网络编程实现简易聊天室
- Socket编程实现多人聊天室(c语言版)
- Android网络编程之Socket通信实现简单聊天室
- LeetCode Search a 2D Matrix
- oracle第2天之sql
- 10大基础实用算法及其图解(程序员必备)
- 【WC2005】【BZOJ1453】Dface双面棋盘
- spring IOC
- Java使用socket网络编程实现多人聊天室
- JSTL之数字、日期格式化<fmt:formatNumber/>、<fmt:formatDate/>
- 1832: [AHOI2008]聚会 LCA
- java中接口和类【转】
- JSON数据的格式及使用
- 大学三年所学总结之数据库
- 寒假小记
- C++栈和队列
- POJ3292 筛法