您的位置:首页 > 理论基础 > 计算机网络

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

2016-01-02 21:17 671 查看
实现原理:客户端之间实现信息共享,需要中间服务器端进行信息转发。设置一个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();
}
}

@Override
public 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();
}

@Override
public void run() {
while(true){//一直监听是否有信息发来
try {
str = in.readUTF();
ta.append(str + "\n");

} catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
public 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!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息