Java学习笔记(二)-------客户端一对多(TCP)多人聊天小程序

来源:互联网 发布:怎样推广app软件 编辑:程序博客网 时间:2024/05/28 11:30

实现原理:客户端之间实现信息共享,需要中间服务器端进行信息转发。设置一个ArrayList,存储客户端列表,服务器每收到消息,就去遍历数组中的Socket并将消息转发。服务器端每连接一个客户端,就产生一个新的线程。具体代码如下:

【服务器端】

package org.ning.study.swing;import java.awt.BorderLayout;import java.awt.Container;import java.awt.FlowLayout;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.border.Border;public class Server2 extends JFrame  {//实现聊天室多人聊天。 客户端一对多通信ServerSocket serverSocket = null;Socket clientSocket = null;ArrayList<Socket> array = null;JTextArea ta;//构造器是没有返回值的public  Server2(){initSwing();initSocket();}public void initSwing(){Container container = this.getContentPane();ta = new JTextArea();container.setLayout(new BorderLayout());container.add(ta,BorderLayout.CENTER);JLabel label = new JLabel("输入聊天内容:");JTextField tf = new JTextField(40);JButton button = new JButton("发送");JPanel south = new JPanel();south.setLayout(new FlowLayout(FlowLayout.LEFT));south.add(label);south.add(tf);south.add(button);container.add(south,BorderLayout.SOUTH);this.setTitle("服务器端程序");this.setBounds(300, 200, 700, 350);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.validate();this.setVisible(true);}public void initSocket(){array = new ArrayList<Socket>();try {serverSocket = new ServerSocket(4331);while(true){clientSocket = serverSocket.accept();//每增加一个客户端,就将其加入到array中array.add(clientSocket);ClientThread clientThread = new ClientThread(clientSocket);Thread t = new Thread(clientThread);t.start();}} catch (IOException e) {e.printStackTrace();}}//主程序入口public static void main(String[] args) {Server2 server = new Server2();}//客户端线程--类中定义的类class ClientThread implements Runnable{private Socket clientSocket;private String str = null;DataInputStream in = null;DataOutputStream out = null;public  ClientThread(Socket clientSocket){this.clientSocket = clientSocket;try {in = new DataInputStream(clientSocket.getInputStream());out = new DataOutputStream(clientSocket.getOutputStream());} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {while(true){try {str = in.readUTF();ta.append(str + "\n");//服务端每次收到的信息,必须向所有的客户端发送DataOutputStream out = null;for(int i = 0; i < array.size(); i++){out = new DataOutputStream(array.get(i).getOutputStream());out.writeUTF(str);}Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}}}}}
【客户端】
package org.ning.study.swing;import java.awt.BorderLayout;import java.awt.Container;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;public class Client2 extends JFrame implements ActionListener, Runnable {Socket clientSocket = null;DataInputStream in = null;DataOutputStream out = null;String str = null;JButton button;JTextField tf;JTextArea ta;Thread thread;public Client2(){thread = new Thread(this);initSwing();initSocket();}public void initSwing(){Container container = this.getContentPane();JPanel panel = new JPanel();JLabel label = new JLabel("输入聊天内容:");tf = new JTextField(40);button = new JButton("发送");button.addActionListener(this);panel.setLayout(new FlowLayout(FlowLayout.LEFT));panel.add(label);panel.add(tf);panel.add(button);ta = new JTextArea();container.setLayout(new BorderLayout());container.add(ta,BorderLayout.CENTER);container.add(panel,BorderLayout.SOUTH);this.setTitle("客户端程序");this.setBounds(300, 200, 700, 350);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.validate();this.setVisible(true);}public void initSocket(){try {clientSocket = new Socket("127.0.0.1", 4331);in = new DataInputStream(clientSocket.getInputStream());out = new DataOutputStream(clientSocket.getOutputStream());} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}//启动线程thread.start();}@Overridepublic void run() {while(true){//一直监听是否有信息发来try {str = in.readUTF();ta.append(str + "\n");} catch (IOException e) {e.printStackTrace();}}}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource() == button){try {out.writeUTF(tf.getText());} catch (IOException e1) {e1.printStackTrace();}}}public static void main(String[] args) {Client2 client = new Client2();}}
【最终效果展示】
我打开了一个服务器端,3个客户端。任何一个客户端发送消息,其他客户端都可以收到。Done!


0 0
原创粉丝点击