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();
}
}
}
}
}
【客户端】
我打开了一个服务器端,3个客户端。任何一个客户端发送消息,其他客户端都可以收到。Done!
【服务器端】
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!
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- 小心服务器内存居高不下的元凶--WebAPI服务
- 运维入门
- [原创]java局域网聊天系统
- Linux5.9无人值守安装
- 数据中心和云未来的十二大趋势
- 用vsftp快速搭建ftp服务器
- Linux快速构建apache web服务器
- 服务器监控策略浅谈
- java socket 注意的地方
- java socket 注意的地方
- 如何降低服务器采购成本 原理分析
- 建议的服务器分区办法
- 服务器托管六大优势分析
- Erlang实现的一个Web服务器代码实例
- 服务器技术全面解析
- C#实现子窗体与父窗体通信方法实例总结
- 保护DNS服务器的几点方法小结