基于java实现的UDP多用户聊天应用
2014-01-10 12:20
453 查看
第一次写博客,还请大家多多指教
因为最近做了一个关于计算机网络的课程设计,是一个多用户聊天软件,实现过程比较简单,现在就拿来和大家分享一下,如果程序有什么不正确的地方希望大家多多提点意见
谢谢大家
以下是具体实现的程序代码
客户端程序:
1.用户运行的第一个界面,用于设置用户名
Setusername.java
Client.java
服务器端:
1.一个User类用于保存用户的信息
User.java
2.服务器实现的类,采用多线程,实现与多个客户端通信,同时转发一个用户的信息给所有的在线用户
MultiThreadServer.java
注:要能正常运行程序还需要导入支持json的包
源程序下载
因为最近做了一个关于计算机网络的课程设计,是一个多用户聊天软件,实现过程比较简单,现在就拿来和大家分享一下,如果程序有什么不正确的地方希望大家多多提点意见
谢谢大家
以下是具体实现的程序代码
客户端程序:
1.用户运行的第一个界面,用于设置用户名
Setusername.java
package zhonghui.client; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; public class Setusername extends JFrame{ private JButton jbt = new JButton("进入聊天室"); private JTextField jtfname= new JTextField(8); public static void main(String[] args) { new Setusername(); } public Setusername(){ final JPanel p1 = new JPanel(); p1.setLayout(new BorderLayout()); p1.add(new JLabel("输入用户名"), BorderLayout.WEST); p1.add(jtfname, BorderLayout.CENTER); jtfname.setHorizontalAlignment(JTextField.LEFT); p1.add(jbt, BorderLayout.EAST); p1.setLayout(new FlowLayout(FlowLayout.LEFT,10,20)); p1.setSize(300, 100); setLayout(new BorderLayout()); add(p1, BorderLayout.CENTER); add(new JLabel("欢迎使用多人聊天系统 ,请输入用户名即可进入聊天室 "), BorderLayout.NORTH); setTitle("多人聊天室 "); setSize(350, 150); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); jbt.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub String username = jtfname.getText().trim(); if(username.equals("")){ }else{ //关闭设置页面,启动聊天框页面 setVisible(false); new Client(username); } } }); // Register listener } }2.用户使用的聊天界面类,实现与服务器通信,本客户端连接的IP是127.0.0.1,即只要服务器在本地运行,即可进行通信
Client.java
package zhonghui.client; import java.io.*; import java.net.*; import java.text.SimpleDateFormat; import java.util.Date; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.TitledBorder; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class Client extends JFrame { /** * */ private static final long serialVersionUID = 1L; // 接受消息框 private JTextField jtf = new JTextField(); private String username=null; // 显示信息框 private JTextArea jta = new JTextArea(); private JTextArea userlist = new JTextArea(10,10); // IO private DataOutputStream toServer; private DataInputStream fromServer; public Client(String username) { this.username=username; //设置输入框 final JPanel p = new JPanel(); p.setLayout(new BorderLayout()); p.add(new JLabel("输入聊天内容(回车发送)"), BorderLayout.WEST); p.add(jtf, BorderLayout.CENTER); jtf.setHorizontalAlignment(JTextField.LEFT); add(p, BorderLayout.SOUTH); //在版面的中间增加一个聊天信息显示框 add(new JScrollPane(jta), BorderLayout.CENTER); jta.setEditable(false); //设置用户列表 final JPanel p2 = new JPanel(); p2.setLayout(new BorderLayout()); p2.setBorder(new TitledBorder("用户列表")); p2.add(new JScrollPane(userlist), BorderLayout.CENTER); userlist.setEditable(false); add(p2, BorderLayout.EAST); jtf.addActionListener(new ButtonListener()); // Register listener setTitle("多人聊天室欢迎你:"+username); setSize(500, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); JSONObject data =new JSONObject(); data.put("username", username); data.put("msg", null); try { //创建一个socket链接服务器 Socket socket = new Socket("127.0.0.1",8000); // 创建一个输入流用于获取服务器的数据 fromServer = new DataInputStream( socket.getInputStream()); // 创建一个输出流用于向服务器发送数据 toServer = new DataOutputStream(socket.getOutputStream()); //向服务器发送数据(用户名) toServer.writeUTF(data.toString()); //开启一个线程,用于读取服务器发送过来的数据 ReadThread readThread = new ReadThread(); readThread.start(); } catch (IOException ex) { jta.append("服务器无响应"); } } private class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { try { // 设置日期格式 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式 String time =df.format(new Date()).toString(); //获取输入框信息 String msg = jtf.getText().trim(); if(msg.equals("")){}else{ //打包数据成json格式 JSONObject data =new JSONObject(); data.put("username", username); data.put("msg", msg); data.put("time",time); //向服务器发送数据 toServer.writeUTF(data.toString()); jtf.setText(""); } } catch (Exception ex) { System.err.println(ex); } } } public class ReadThread extends Thread { public void run() { String json = null; try { //无线循环监听服务器发来的数据 while (true) { //读取服务器的数据 json = fromServer.readUTF(); //转化成json格式 JSONObject data = JSONObject.fromObject(json.toString()); if(json != null){ //打印聊天信息或者系统提示信息 jta.append( data.getString("msg") + "\n"); //强制使光标移动最底部 jta.selectAll(); //刷新用户列表 String list = ""; JSONArray jsonArray = data.getJSONArray("userlist"); for(int i=0;i<jsonArray.size();i++){ list=list+jsonArray.get(i)+"\n"; } userlist.setText(list); } } } catch (Exception e) { e.printStackTrace(); } } } }
服务器端:
1.一个User类用于保存用户的信息
User.java
package zhonghui.server; import java.net.Socket; public class User { private String UserName=""; private Socket socket; public String getUserName() { return UserName; } public void setUserName(String userName) { UserName = userName; } public Socket getSocket() { return socket; } public void setSocket(Socket socket) { this.socket = socket; } }
2.服务器实现的类,采用多线程,实现与多个客户端通信,同时转发一个用户的信息给所有的在线用户
MultiThreadServer.java
package zhonghui.server; import java.io.*; import java.net.*; import java.util.*; import java.awt.*; import javax.swing.*; import net.sf.json.JSONObject; public class MultiThreadServer extends JFrame { private static final long serialVersionUID = 1L; // 服务器启动的时候新建一个聊天组 //这是一个用户信息列表 ArrayList<User> clientList = new ArrayList<User>(); //这是在线用户名列表 ArrayList<String> usernamelist = new ArrayList<String>(); //创建一个信息显示框 4000 private JTextArea jta = new JTextArea(); //声明一个用户对象,该类里面有两个变量 socket,username; private User user = null; //声明一个输出流 DataOutputStream output = null; //声明一个输入流 DataInputStream input = null; public static void main(String[] args) { new MultiThreadServer(); } public MultiThreadServer() { // 设置信息显示框版面 setLayout(new BorderLayout()); add(new JScrollPane(jta), BorderLayout.CENTER); jta.setEditable(false); setTitle("多人聊天服务器 "); setSize(500,300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // try { // 创建一个服务器socket,绑定端口8000 ServerSocket serverSocket = new ServerSocket(8000); //打印启动时间 jta.append("服务器启动时间 " + new Date() + '\n'); //无限循环监听是否有新的客户端连接 while (true) { // 监听一个新的连接 Socket socket = serverSocket.accept(); if(socket!=null){ //获取上线用户的信息 input = new DataInputStream( socket.getInputStream()); String json = input.readUTF(); JSONObject data = JSONObject.fromObject(json.toString()); jta.append("用户:" + data.getString("username") + "在" + new Date()+"登陆系统" + '\n'); //显示用户登录ip地址 InetAddress inetAddress = socket.getInetAddress(); jta.append("用户" + data.getString("username") + "的IP地址是:" + inetAddress.getHostAddress() + "\n"); //新建一个用户对象 user = new User(); //设置该用户对象的socket user.setSocket(socket); //设置用户名 user.setUserName(data.getString("username")); //加入在线用户组列表 clientList.add(user); //加入用户名列表(用户显示在客户端的用户列表) usernamelist.add(data.getString("username")); } //用户上线提示,打包成json格式数据 JSONObject online = new JSONObject(); online.put("userlist", usernamelist); online.put("msg", user.getUserName()+"上线了"); //提示所有用户有新的用户上线 for (int i = 0; i < clientList.size(); i++) { try{ User otheruser = clientList.get(i); //获取每一个用户的socket,得到输出流, output = new DataOutputStream(otheruser.getSocket().getOutputStream()); //向每个用户端发送数据 output.writeUTF(online.toString()); }catch(IOException ex){ System.err.println(ex); } } //新开一个线程,并将当前连接用户的socket传给这个线程,该线程用于负责监听该socket的数据 HandleAClient task = new HandleAClient(socket); new Thread(task).start(); } }catch(IOException ex) { System.err.println(ex); } } // 线程类 class HandleAClient implements Runnable { private Socket socket; //已连接的cocket public HandleAClient(Socket socket) { this.socket = socket; } public void run() { try { // 获取本线程监听的socket客户端的输入流 DataInputStream inputFromClient = new DataInputStream( socket.getInputStream()); // 循环监听 while (true) { // 获取客户端的数据 String json = inputFromClient.readUTF(); JSONObject data = JSONObject.fromObject(json.toString()); //将获取的数据转发给每一个用户 for (int i = 0; i < clientList.size(); ) { try{ //将聊天的信息和用户列表打包成json格式数据发给每个客户端 JSONObject chat = new JSONObject(); chat.put("userlist", usernamelist); chat.put("msg", data.getString("username")+" "+data.getString("time")+":\n"+data.getString("msg")); User otheruser = clientList.get(i); output = new DataOutputStream(otheruser.getSocket().getOutputStream()); output.writeUTF(chat.toString()); i++; }catch(IOException ex){ //如果出现异常,表明当前循环的客户端下线了 //从列表中移除 User outuser = clientList.get(i); clientList.remove(i); //提示每个用户有用户下线了 usernamelist.remove(outuser.getUserName()); JSONObject out = new JSONObject(); out.put("userlist", usernamelist); out.put("msg", outuser.getUserName()+"下线了\n"); //通知下线 for (int j = 0; j < clientList.size(); j++) { try{ User otheruser = clientList.get(j); output = new DataOutputStream(otheruser.getSocket().getOutputStream()); output.writeUTF(out.toString()); }catch(IOException ex1){ } } } } } } catch(IOException e) { System.err.println(e); } } } }
注:要能正常运行程序还需要导入支持json的包
源程序下载
相关文章推荐
- Java基于UDP用Socket实现点对点聊天
- java基于udp实现键盘录入聊天
- 网络编程应用:基于UDP协议【实现聊天程序】--练习
- Java 实现基于UDP的用户登录
- Java_乔晓松_Java网络编程UDP实现黑窗口聊天
- 基于Qt的UDP传输文字聊天小软件实现
- Java实现基于邻接表的图的几个应用
- JAVA学习第六十课 — UDP协议 &基于多线程模拟简单的QQ聊天程序
- C#基于UDP实现的P2P语音聊天工具
- 在 Android 的 IM 应用中使用 asmack 库实现用户头像的传输(基于VCard协议)
- JAVA中基于UDP实现多线程通信
- Java数据结构与算法之数组应用——用户登陆与注册数组实现
- Java 实现基于 UDP 的简单 socket 通信
- 网络编程应用:基于UDP协议【实现文件下载】--练习
- 在 Android 的 IM 应用中使用 asmack 库实现用户头像的传输(基于VCard协议)
- 关于基于java的用户角色权限系统的前后台实现构想
- Java 开发基于Zookeeper,Spring,vue.js的高并发多用户模块化微信商城系统(四) Java微框架Spring Boot的应用
- java实现基于TCP协议带界面的多人聊天代码
- c#基于udp实现的p2p语音聊天工具
- 网络编程与多线程的应用--基于socket udp编写一个简单聊天程序