Android客户端简单的聊天程序达成
发布时间:2021-11-22 14:26:53 所属栏目:教程 来源:互联网
导读:看看今天实现的Android聊天室的聊天功能吧,先说说服务器端的代码及其功能吧 server.Java : 负责服务器的界面,以及更服务器主线程ServerThread的启动,产生了BroadCast广播,产生ClientThread线程 ServerThread.java:服务器监听的端口线程,负责创建ServerS
看看今天实现的Android聊天室的聊天功能吧,先说说服务器端的代码及其功能吧 server.Java : 负责服务器的界面,以及更服务器主线程ServerThread的启动,产生了BroadCast广播,产生ClientThread线程 ServerThread.java:服务器监听的端口线程,负责创建ServerSocket及监听是否有新的客户端连接,并记录客户端连接及需要发送的信息,产生了BroadCast广播 BroadCast.java: 服务器向客户端广播线程,负责向客户端发送消息,产生ClientThread线程 ClientThread.java:维持服务器和单个客户端的连接线程,负责接受客户端发来是信息 好了接着就看看他们的代码吧!! 1.server.java-------创建ServerThread对象启动run方法 package com.wang; import java.awt.BorderLayout; import javax.swing.*; import java.awt.event.*; public class Server extends JFrame implements ActionListener { /**** *服务器端主程序负责界面,以及服务段主线程ServerThread的启动 * 服务端主线程ServerThread又产生BroadCast及ClientThread线程 建立服务器端主界面中所用到的布局方式 ***/ // 边框容器 BorderLayout borderLayout1 = new BorderLayout(); BorderLayout borderLayout2 = new BorderLayout(); // 创建面板 JPanel jPanel1 = new JPanel(); JPanel jPanel2 = new JPanel(); // 创建按钮 JButton jButton1 = new JButton(); JButton jButton2 = new JButton(); JScrollPane jScrollPane1 = new JScrollPane(); // 创建服务器端接收信息文本框 static JTextArea jTextArea1 = new JTextArea(); boolean bool = false, start = false; // 声明ServerThread线程类对象 ServerThread serverThread; Thread thread; // 构造函数,用于初始化 public Server() { super("Server"); // 设置内容面板布局方式 getContentPane().setLayout(borderLayout1); // 初始化按钮组件 jButton1.setText("启动服务器"); // 按钮的动作设置监听事件 jButton1.addActionListener(this); jButton2.setText("关闭服务器"); // 按钮的动作设置监听事件 jButton2.addActionListener(this); // 初始化jPanel1面板对象,并向其中加入组件,上北 this.getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH); jPanel1.add(jButton1); jPanel1.add(jButton2); // 初始化jPanel2面板对象,并向其中加入组件, jTextArea1.setText(""); jPanel2.setLayout(borderLayout2); jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER); jScrollPane1.getViewport().add(jTextArea1); this.getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER); this.setSize(400, 400); this.setVisible(true); } public static void main(String[] args) { Server sever = new Server(); sever.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } // 服务器界面中按钮事件处理 public void actionPerformed(ActionEvent e) { if (e.getSource() == jButton1) { // 声明一个ServerThread对象 serverThread = new ServerThread(); serverThread.start(); } else if (e.getSource() == jButton2) { bool = false; start = false; serverThread.finalize(); this.setVisible(false); } } } 2.ServerThread.java -----创建Broadcast对象,启动该线程,实现run方法后,不断的向客户端发送消息,ServerThread开启后,不断的获取新的客户端并监听是否发送消息 package com.wang; import java.util.*; import java.io.*; import java.net.*; public class ServerThread extends Thread // 服务器监听端口线程 { // 声明ServerSocket类对象 ServerSocket serverSocket; // 指定服务器监听端口常量 public static final int PORT = 80; /** * 创建一个Vector对象,用于存储客户端连接的ClientThread对象 , ClientThread类维持服务器与单个客户端的连接线程 * 负责接收客户端发来的信息,clients负责存储所有与服务器建立连接的客户端 **/ Vector<ClientThread> clients; // 创建一个Vector对象,用于存储客户端发送过来的信息 Vector<Object> messages; // BroadCast类负责服务器向客户端广播消息 BroadCast broadcast; String ip; InetAddress myIPaddress = null; public ServerThread() { /*** * 创建两个Vector数组非常重要 , clients负责存储所有与服务器建立连接的客户端, * messages负责存储服务器接收到的未发送出去的全部客户端的信息 * **/ clients = new Vector<ClientThread>(); messages = new Vector<Object>(); try { // 创建ServerSocket类对象 serverSocket = new ServerSocket(PORT); } catch (IOException E) { } // 获取本地服务器地址信息 try { myIPaddress = InetAddress.getLocalHost(); } catch (UnknownHostException e) { System.out.println(e.toString()); } ip = myIPaddress.getHostAddress(); Server.jTextArea1.append("服务器地址:" + ip + "端口号:" + String.valueOf(serverSocket.getLocalPort()) + "n"); // 创建广播信息线程并启动 broadcast = new BroadCast(this); broadcast.start(); } /** * 注意:一旦监听到有新的客户端创建即new Socket(ip, PORT)被执行, * 就创建一个ClientThread来维持服务器与这个客户端的连接 **/ public void run() { while (true) { try { // 获取客户端连接,并返回一个新的Socket对象 Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress().getHostAddress()); // 创建ClientThread线程并启动,可以监听该连接对应的客户端是否发送来消息, 并获取消息 ClientThread clientThread = new ClientThread(socket, this); clientThread.start(); if (socket != null) { synchronized (clients) { // 将客户端连接加入到Vector数组中保存 clients.addElement(clientThread); } } } catch (IOException E) { System.out.println("发生异常:" + E); System.out.println("建立客户端联机失败!"); System.exit(2); } } } public void finalize() { try { // 关闭serverSocket方法 serverSocket.close(); } catch (IOException E) { } serverSocket = null; } } 3.BroadCast.java------ package com.wang; import java.io.*; public class BroadCast extends Thread { // 服务器向客户端广播线程 ClientThread clientThread; // 声明ServerThread对象 ServerThread serverThread; String str; public BroadCast(ServerThread serverThread) { this.serverThread = serverThread; } // 该方法的作用是不停地向所有客户端发送新消息 public void run() { while (true) { try { // 线程休眠200 ms Thread.sleep(200); } catch (InterruptedException E) { } // 同步化serverThread.messages synchronized (serverThread.messages) { // 判断是否有未发的消息 if (serverThread.messages.isEmpty()) { continue; } // 获取服务器端存储的需要发送的第一条数据信息 str = (String) this.serverThread.messages.firstElement(); } // 同步化serverThread.clients synchronized (serverThread.clients) { // 利用循环获取服务器中存储的所有建立的与客户端的连接 for (int i = 0; i < serverThread.clients.size(); i++) { clientThread = (ClientThread) serverThread.clients .elementAt(i); try { // 向记录的每一个客户端发送数据信息 clientThread.out.writeUTF(str); } catch (IOException E) { } } // 从Vector数组中删除已经发送过的那条数据信息 this.serverThread.messages.removeElement(str); } } } } 4.ClientThread.java----获得Socket的输入输出流,向客户端接收或者发送数据 package com.wang; import java.net.*; import java.io.*; public class ClientThread extends Thread { /** * 维持服务器与单个客户端的连接线程,负责接收客户端发来的信息, * 声明一个新的Socket对象, * 用于保存服务器端用accept方法得到的客户端的连接 **/ Socket clientSocket; //声明服务器端中存储的Socket对象的数据输入/输出流 DataInputStream in = null; DataOutputStream out = null; //声明ServerThread对象 ServerThread serverThread; public ClientThread(Socket socket,ServerThread serverThread) { clientSocket=socket; this.serverThread=serverThread; try { //创建服务器端数据输入/输出流 in = new DataInputStream(clientSocket.getInputStream()); out = new DataOutputStream(clientSocket.getOutputStream()); } catch (IOException e2) { System.out.println("发生异常"+e2); System.out.println("建立I/O通道失败!"); System.exit(3); } } //该方法监听该连接对应得客户端是否有消息发送 public void run() { while(true) { try { //读入客户端发送来的信息 String message=in.readUTF(); synchronized(serverThread.messages) { if(message!=null) { //将客户端发送来得信息存于serverThread的messages数组中 serverThread.messages.addElement(message); //在服务器端的文本框中显示新消息 Server.jTextArea1.append(message+'n'); } } } catch(IOException E){break;} } } } 5.接着看看手机客户端的布局main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/username" android:layout_width="270dp" android:layout_height="wrap_content" android:hint="请输入用户名:" android:maxLength="10" > </EditText> <Button android:id="@+id/LoginButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登陆" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/ip" android:layout_width="270dp" android:layout_height="wrap_content" android:digits=".1234567890" android:hint="10.254.1.62" > </EditText> <Button android:id="@+id/LeaveButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="退出" /> </LinearLayout> <EditText android:id="@+id/history" android:layout_width="fill_parent" android:layout_height="280dp" > </EditText> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/message" android:layout_width="270dp" android:layout_height="wrap_content" > </EditText> <Button android:id="@+id/SendButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送" /> </LinearLayout> </LinearLayout> ![]() (编辑:江门站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |