加入收藏 | 设为首页 | 会员中心 | 我要投稿 江门站长网 (https://www.0750zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

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>  
 

(编辑:江门站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读