基于安卓4.4的socket通信——文字聊天

来源:互联网 发布:华为工作知乎 编辑:程序博客网 时间:2024/05/24 02:12

       学习了3个月安卓了,今天开始写点东西。

      这个安卓的聊天demo,还是分为客户端、服务器两大部分,先来看看客户端:

      界面代码如下:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);this.requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);init();//打开应用就默认连接cHandler.sendEmptyMessage(0x01);}private void init() {cButtonSend = (Button) findViewById(R.id.btn);cName = (EditText) findViewById(R.id.yhm);cToName = (EditText) findViewById(R.id.jsm);cEditTextContent = (EditText) findViewById(R.id.et);cList = (ListView) findViewById(R.id.listview);mAdapter = new ChatMsgViewAdapter(this, mDataArrays);cList.setAdapter(mAdapter);cButtonSend.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if( cName.getText().toString().equals("") || cName.getText().toString()==null || cToName.getText().toString().equals("") || cToName.getText().toString()==null || cEditTextContent.getText().toString().equals("") || cEditTextContent.getText().toString()==null){new AlertDialog.Builder(MainActivity.this).setTitle("").setMessage("请填写完整!").setPositiveButton("确定", null).show();}else{//发送信息展现ChatMsgEntity entity = new ChatMsgEntity();entity.setDate(getDate());entity.setName(cName.getText().toString());entity.setMsgType(false);entity.setText(cEditTextContent.getText().toString());mDataArrays.add(entity);mAdapter.notifyDataSetChanged();cList.setSelection(cList.getCount() - 1);cHandler.sendEmptyMessage(0x01);//清楚输入框内容cEditTextContent.setText("");}}});}
     socket相关代码:

Handler cHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 0x01:cThread = new Thread() {@Overridepublic void run() {super.run();DataInputStream dis = null;DataOutputStream dos = null;try {// 阻塞函数,正常连接后才会向下继续执行cSocket = new Socket(ADDRESS, PORT);dis = new DataInputStream(cSocket.getInputStream());dos = new DataOutputStream(cSocket.getOutputStream());if(mDataArrays.isEmpty()){//刚打开应用,只是建立连接}else{// 向服务器写数据ChatMsgEntity e = new ChatMsgEntity();e = mDataArrays.get(mDataArrays.size()-1);dos.writeUTF(e.getName());dos.writeUTF(cToName.getText().toString());dos.writeUTF(e.getText().toString());// 读取服务器发来的数据//cContent += dis.readUTF();recive1 = dis.readUTF();recive2 = dis.readUTF();if(recive1.equals("错误*001\n我不在线")){//对方不在线,发送失败cHandler.sendEmptyMessage(0x03);}else{//接收信息展现cHandler.sendEmptyMessage(0x04);}}} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (dis == null) {dis.close();}if (dos == null) {dos.close();}} catch (IOException e) {e.printStackTrace();}//cHandler.sendEmptyMessage(0x02);}}};cThread.start();break;case 0x02://cTextViewContent.setText(cContent);break;case 0x03://对方不在线,发送失败recive(recive2, recive1);break;case 0x04://接收信息展现recive(recive1, recive2);break;default:break;}}};

     下面是接收服务端返回的消息(包括他人发送给你,和你发送消息,但是对方不在线返回的消息)

     其中关键是修改界面必须要在主线程中完成:mAdapter.notifyDataSetChanged();

public void recive(String a, String b){ChatMsgEntity e = new ChatMsgEntity();e.setName(a);e.setMsgType(true);e.setText(b);e.setDate(getDate());mDataArrays.add(e);mAdapter.notifyDataSetChanged();cList.setSelection(cList.getCount() - 1);}

     最后不要忘了配置相关权限,

 <!-- 添加联网权限 -->    <uses-permission android:name="android.permission.INTERNET" />


     接下去看服务端代码:

     

public class MultiThreadServer {    private int port=8888;    private ServerSocket serverSocket;    private static ExecutorService executorService;//线程池    private final int POOL_SIZE=10;//单个CPU线程池大小    static HashMap<String, Socket> map=new HashMap<String, Socket>();//保存链接        public MultiThreadServer() throws IOException{        serverSocket=new ServerSocket(port);        //Runtime的availableProcessor()方法返回当前系统的CPU数目.        setExecutorService(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE));        System.out.println("服务器启动");    }        public void service(){        while(true){            Socket socket=null;            try {                //接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接                socket=serverSocket.accept();                getExecutorService().execute(new Handler(socket));                            } catch (Exception e) {                e.printStackTrace();            }        }    }        public static void main(String[] args) throws IOException {        new MultiThreadServer().service();    }public static ExecutorService getExecutorService() {return executorService;}public void setExecutorService(ExecutorService executorService) {MultiThreadServer.executorService = executorService;}}class Handler implements Runnable{    private Socket socket;    public Handler(Socket socket){        this.socket=socket;    }        public void run(){        DataInputStream dis = null;DataOutputStream dos = null;try {while (true) {System.out.println("正在等待客户连接...");// 这里处于等待状态,如果没有客户端连接,程序不会向下执行dis = new DataInputStream(socket.getInputStream());dos = new DataOutputStream(socket.getOutputStream());// 读取数据String fp = dis.readUTF();String tp = dis.readUTF();String clientStr = dis.readUTF();System.out.println("---客户端已成功连接---");MultiThreadServer.map.put(fp, socket);// 得到客户端的IPSystem.out.println("客户端的IP=" + socket.getInetAddress());// 得到客户端的端口号System.out.println("客户端的端口号=" + socket.getPort());// 得到本地端口号System.out.println("本地服务器端口号=" + socket.getLocalPort());System.out.println("信息:" + fp +"对"+ tp +"说:"+ clientStr);System.out.println("---------------------------------");//判断接收方 是否在线if(MultiThreadServer.map.containsKey(tp)){Socket socket1=MultiThreadServer.map.get(tp);DataOutputStream out=new DataOutputStream(socket1.getOutputStream());out.writeUTF(fp);out.writeUTF(clientStr);out.flush();}else{// 写出数据dos.writeUTF("错误*001\n我不在线");dos.writeUTF(tp);}//消息转发不能新建一个socket,原来端口被占用 会报错//MultiThreadServer.getExecutorService().execute(new Handler1(socket.getInetAddress().toString(),socket.getPort(),clientStr,fp));}}catch (EOFException e) { System.out.println("这是合法的,客户端连接已断开");}catch (IOException e) {e.printStackTrace();} finally {try {if (dis != null) {dis.close();}if (dos != null) {dos.close();}// if(socket!=null){// socket.close();// }                  } catch (IOException e) {e.printStackTrace();}}    }}

     下面看一下运行效果:


    如上图,是自己发送消息给自己,下图为发送给别人。


     安卓文本聊天的至此完结,虽然还有很多不足,以后有机会再改了。

0 0
原创粉丝点击