Android 聊天室的开发

来源:互联网 发布:mysql主键是主键长度 编辑:程序博客网 时间:2024/05/21 22:48

刚开始接触Android的网络通信开发。
目前自己写了一个聊天室的小程序,记录一下。

本程序包括:

1.服务器:由java开发
2.客户端:由Android开发

首先贴上演示效果。先开启服务端程序以后,再打开客户端。
这里写图片描述

服务器的console起到接受并且转发的目的:

这里写图片描述

服务端代码:

package com.ustclin.talk;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;public class Server {    //private static final String IP_ADDRESS = "192.168.0.200";    private static final int PORT = 18888;    private static int num = 0;    public static ArrayList<Socket> socketList = new ArrayList<Socket>();    /**     * @param args     */    public static void main(String[] args) {        ServerSocket serverSocket = null;        System.out.println("ServerSocket Begin........");        try {            serverSocket = new ServerSocket(PORT);            // 使用循环方式一直等待客户端的连接            while (true) {                num++;                Socket accept = serverSocket.accept();                socketList.add(accept);                System.out.println("arrayList num = "+socketList.size());                // 启动一个新的线程,接管与当前客户端的交互会话                new Thread(new ServerThread(accept , "Client "+num ), "Client " + num).start();            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                serverSocket.close();                System.out.println("---->  serverSocket closed.");            } catch (IOException e) {                e.printStackTrace();            }        }    }}/** * @author JCC 服务器处理客户端会话的线程 */class ServerThread implements Runnable {    Socket socket = null;    String clientName = null;    public ServerThread(Socket socket , String clientName) {        System.out.println("Create a new ServerThread...");        this.socket = socket;        this.clientName = clientName;    }    @Override    public void run() {        try {            // 接收客户端消息            BufferedReader in = new BufferedReader(new InputStreamReader(                    socket.getInputStream()));            while (true) {                String message = null;                if (!socket.isClosed()) {                    try {                        message = in.readLine();                    } catch (Exception e) {                        e.printStackTrace();                    }                    if(null == message){                        // the socket is null , means that the client is disconnect                        Server.socketList.remove(socket);                        break;                    }                    System.out.println("server read Line from "+ clientName + " success! message = " + message);                    for(Socket ss : Server.socketList){                        // 发送消息,向客户端                        PrintWriter out = new PrintWriter(new BufferedWriter(                                new OutputStreamWriter(ss.getOutputStream())), true);                        out.println(this.clientName +": "+ message);                        System.out.println("Thread " + clientName + " socket send out");                    }                }            }        }        catch (IOException e) {            e.printStackTrace();        } finally {                System.out.println("out of while");        }    }}interface Constant {    public static final String SERVER_IP = "192.168.0.200";    public static final int PORT = 19999;}

客户端主程序:

package com.ustc.linkun.chat;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private static final String TAG = "ConnectToServer";    private static final String CONNECTED = "connected ! ";    private static final String CONNECTINGSERVER = "connecting ...";    private TextView tvForIpAddress;    private TextView tvForPort;    private EditText mIpAddress;    private EditText mPort;    private Button mConnect;    private TextView mServerMsg;    private EditText editText;    private Button button1;    private static final int SEND_DATA = 0;    private static final int GET_DATA_FROM_SERVER = 1;    private static final int CONNECT_TO_SERVER = 2;    private static final int CONNECTING = 3;    private MyHandler myHandler;    private Socket socket = null;    private Context mContext;    /**     * Called when the activity is first created.     */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mContext = this;        tvForIpAddress = (TextView) findViewById(R.id.tvForIpAddress);        tvForPort = (TextView) findViewById(R.id.tvForPort);        mIpAddress = (EditText)findViewById(R.id.ipAddress);        mPort = (EditText) findViewById(R.id.port);        mConnect = (Button) findViewById(R.id.connect);        editText = (EditText) findViewById(R.id.editText1);        mServerMsg = (TextView) findViewById(R.id.serverMsg);        //mServerMsg.setEnabled(false);        button1 = (Button) findViewById(R.id.button1);        myHandler = new MyHandler();        mConnect.setOnClickListener(this);        button1.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            // connect server            case R.id.connect:                // connecting , avoid multi button click which can result sending multi-connect request                Runnable r0 = new Runnable() {                    @Override                    public void run() {                        Message msg = myHandler.obtainMessage();                        msg.what = CONNECTING;                        myHandler.sendMessage(msg);                    }                };                new Thread(r0).start();                // use for connection                Runnable r1 = new Runnable() {                    @Override                    public void run() {                        initSocket();                        ClientThread ct = new ClientThread(socket , "Client");                        new Thread(ct).start();                        //connectToServer(mIpAddress.getText().toString(), Integer.parseInt(mPort.getText().toString()));                        if(socket.isConnected()){                            Message msg = myHandler.obtainMessage();                            msg.what = CONNECT_TO_SERVER;                            myHandler.sendMessage(msg);                        }                    }                };                new Thread(r1).start();                break;            // send data            case R.id.button1:                Runnable r2 = new Runnable() {                    @Override                    public void run() {                        Message msg = myHandler.obtainMessage();                        String str = editText.getText().toString();                        System.out.println(">>>>editText: " +str);                        Bundle bundle = new Bundle();                        bundle.putString("content", str);                        msg.what = SEND_DATA;                        msg.setData(bundle);                        myHandler.sendMessage(msg);                    }                };                new Thread(r2).start();                break;            default:                break;        }    }    private void initSocket() {        try{            //socket = new Socket(ipAddress , port);            socket = new Socket(mIpAddress.getText().toString(),Integer.parseInt(mPort.getText().toString()));            socket.setKeepAlive(true);            socket.setSoTimeout(10 * 60 * 1000);        } catch (Exception e){            e.printStackTrace();        }    }    //private class    private class MyHandler extends Handler {        public MyHandler() {        }        public MyHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what){                case SEND_DATA:                    //Bundle bundle = new Bundle();                    final String str = (String)msg.getData().get("content");                    System.out.println(">>>>>content : " + str);                    if(str.equals("")){                        Toast.makeText(mContext,"不能发送空内容!",Toast.LENGTH_SHORT).show();                    }                    else {                        new Thread(new Runnable() {                            @Override                            public void run() {                                sendData(str);                            }                        }).start();                        editText.setText("");                        //mServerMsg.append(str);                    }                    break;                case GET_DATA_FROM_SERVER:                    String str1 = (String) msg.getData().get("content");                    System.out.println("myHandler get str = " + str1);                    mServerMsg.append("\n"+str1);                case CONNECT_TO_SERVER:                    mIpAddress.setEnabled(false);                    mPort.setEnabled(false);                    mConnect.setText(CONNECTED);                    tvForIpAddress.setVisibility(View.GONE);                    tvForPort.setVisibility(View.GONE);                    mIpAddress.setVisibility(View.GONE);                    mPort.setVisibility(View.GONE);                    mConnect.setVisibility(View.GONE);                    //mServerMsg.setText("The Server is connected!");                case CONNECTING:                    mConnect.setText(CONNECTINGSERVER);                    mConnect.setEnabled(false);                default:                    break;            }        }    }    // send data    private void sendData(String content) {        // server is on        try {            //String content = editText.getText().toString();            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter                    (socket.getOutputStream())), true);            //发送数据            out.println(content);            System.out.println(">>>>>send out SUCCESSFUL!");        } catch (Exception e) {            e.printStackTrace();        }    }    //    private void send_CONNECTION_CLOSE_DATA(){        try {            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter                    (socket.getOutputStream())), true);            //发送数据            out.println("closing-connection");            System.out.println("closing-connection");        } catch (Exception e){            e.printStackTrace();        }    }    // close the connection to the server    @Override    protected void onDestroy() {        super.onDestroy();        try {            if (null != socket) {                new Thread(new Runnable() {                    @Override                    public void run() {                        send_CONNECTION_CLOSE_DATA();                    }                });                socket.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }    private class ClientThread implements Runnable{        private Socket socket = null;        private String name;        public ClientThread(Socket socket , String threadName){            this.socket = socket;            this.name = threadName;        }        @Override        public void run() {            try {                // 接收客户端消息                BufferedReader in = new BufferedReader(new InputStreamReader(                        socket.getInputStream()));                while (true) {                    String message = null;                    try {                        if (!socket.isClosed()) {                            message = in.readLine();                            System.out.println("Server:" + message);                            Message msg = myHandler.obtainMessage();                            Bundle b = new Bundle();                            b.putString("content" , message);                            msg.setData(b);                            msg.what = GET_DATA_FROM_SERVER;                            myHandler.sendMessage(msg);                            System.out.println("read Line success! message = " + message);                        }                        Thread.sleep(1000);                    } catch (IOException e) {                        e.printStackTrace();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                //in = socket.getInputStream();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

客户端界面布局:

<?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">    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:id="@+id/tvForIpAddress"        android:text="IP Address: " />    <EditText        android:id="@+id/ipAddress"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="input the ip address here"        android:text="192.168.0.200">    </EditText>    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:id="@+id/tvForPort"        android:text="port: " />    <EditText        android:id="@+id/port"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="input the port number here"        android:text="18888">    </EditText>    <Button        android:id="@+id/connect"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="connect">    </Button>    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:text="----Talk----" />    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/serverMsg"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="This is for TALK History zone" />    </RelativeLayout>    <EditText        android:id="@+id/editText1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:hint="">    </EditText>    <Button        android:id="@+id/button1"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="send">    </Button></LinearLayout>
  1. 先运行Server.java , 保证服务器在客户端之前开启

  2. 客户端是用Android Studio开发的,可以直接导入。如果你的IDE是ADT,
    则可以选择性得添加里边的MainActivity.java 和 main.xml布局文件。需要
    注意的是,AndroidManifest.xml文件需要添加访问INTERNET的权限

  3. 运行多个客户端,配置好服务器的IP地址后,即可进行聊天。

具体的源码大家可以去看看:基于socket的Android聊天程序

0 0
原创粉丝点击