android socket聊天室功能实现

android socket聊天室功能实现,第1张

概述前提概要笔者很久之前其实就已经学习过了socket,当然也是用socket做过了聊天室,但是觉得此知识点比较一般,并无特别难的技术点,于是也并未深究。

前提概要

笔者很久之前其实就已经学习过了socket,当然也是用socket做过了聊天室,但是觉得此知识点比较一般,并无特别难的技术点,于是也并未深究。
然而近期一个项目中对socket的使用却让笔者感觉socket强大无比,可以实现诸多功能

个人Socket体验

项目主要有关智能家居,需要实现多台手机同时对灯进行 *** 作(开或者关),主要需要实现以下几点:

1、进入界面时获取所有灯的状态。
2、一台手机改变了灯的状态,其他的手机上可以有所显示。
3、硬件上改变了灯的状态(手动开关灯),所有手机上要有所显示。

此功能如果使用http读取的方式实现就不太合适了。一方面客户端与服务器读取文件的同步性难以保证,即使保证了,也需要浪费大量性能;另一方面,类似笔者的这种项目功能服务器和客户端交互比较频繁,对“即时性”要求也比较高,用http不仅性能消耗太大,而且难以保证“即时性”。

但是使用Socket就很容易实现了,主要逻辑如下:

1、每次进入界面与服务器建立Socket连接,并得到此时灯的状态
2、每次需要对灯进行 *** 作的时候建立一个线程把灯的状态传递给服务器,服务器接收到之后,把该状态传递给每一个此时与服务器建立连接的客户端。

此次体验也是让笔者想起了学长之前做的一道笔试题,题目大概如下:

将淘宝网页和手机版同时打开账户,手机停留在购物车界面,此时网页上将某一物品加入购物车,如何设计才能让手机自动刷新购物车。

如果使用socket,相信是一个不错的思路。

好了,接下来进入正题,展示socket聊天室demo。

效果(源码在文章结尾)

主要思路

AndroID

1、进入界面客户端与服务器建立socket,同时此时开启一个线程一直接收服务器发送来的消息。
2、每次点击button获取EditText中的字符串,调用子线程把字符串发送给服务器。

服务器

1、创建一个ArrayList存储Socket。
2、循环接收请求访问该端口的客户端,接收到之后,把该socket存储到ArrayList中,并且为每一个socket开启一个线程用于通信。
3、每个socket的线程的逻辑如下:循环接收客户端发来的消息,接收到之后,利用之前的ArrayList,发送到每一个客户端。如果某个客户端返回空值或者无法发送过去,那么表示该客户端已经断开,就从ArrayList中移除。

代码

(借鉴《AndroID疯狂讲义》)

AndroID

不要忘记在AndroIDManifest里面加上访问网络的权限

MainActivity:

package com.example.double2.sockettesttwo;import androID.os.Bundle;import androID.os.Handler;import androID.os.Message;import androID.support.v7.app.AppCompatActivity;import androID.vIEw.VIEw;import androID.Widget.button;import androID.Widget.EditText;import androID.Widget.TextVIEw;public class MainActivity extends AppCompatActivity { private EditText etMain; private button btnMain; private TextVIEw tvMain; private ClIEntThread mClIEntThread; //在主线程中定义Handler传入子线程用于更新TextVIEw private Handler mHandler; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); etMain = (EditText) findVIEwByID(R.ID.et_main); btnMain = (button) findVIEwByID(R.ID.btn_main); tvMain = (TextVIEw) findVIEwByID(R.ID.tv_main); mHandler=new Handler() {  @OverrIDe  public voID handleMessage(Message msg) {  if (msg.what == 0) {   tvMain.append("\n" + msg.obj.toString());  }  } }; //点击button时,获取EditText中string并且调用子线程的Handler发送到服务器 btnMain.setonClickListener(new VIEw.OnClickListener() {  @OverrIDe  public voID onClick(VIEw v) {  try {   Message msg = new Message();   msg.what = 1;   msg.obj = etMain.getText().toString();   mClIEntThread.revHandler.sendMessage(msg);   etMain.setText("");  } catch (Exception e) {   e.printstacktrace();  }  } }); mClIEntThread = new ClIEntThread(mHandler); new Thread(mClIEntThread).start(); }}

ClIEntThread

package com.example.double2.sockettesttwo;import androID.os.Handler;import androID.os.Looper;import androID.os.Message;import androID.util.Log;import java.io.BufferedReader;import java.io.IOException;import java.io.inputStreamReader;import java.io.OutputStream;import java.net.socket;/** * 项目名称:SocketTestTwo * 创建人:Double2号 * 创建时间:2016.11.20 9:16 * 修改备注: */public class ClIEntThread implements Runnable { private Socket mSocket; private BufferedReader mBufferedReader = null; private OutputStream mOutputStream = null; private Handler mHandler; public Handler revHandler; public ClIEntThread(Handler handler) { mHandler = handler; } @OverrIDe public voID run() { try {  mSocket = new Socket("10.3.20.159",30003);  Log.d("xjj","connect success");  mBufferedReader = new BufferedReader(new inputStreamReader(mSocket.getinputStream()));  mOutputStream = mSocket.getoutputStream();  new Thread(){  @OverrIDe  public voID run() {   super.run();   try {   String content = null;   while ((content = mBufferedReader.readline()) != null) {    Log.d("xjj",content);    Message msg = new Message();    msg.what = 0;    msg.obj = content;    mHandler.sendMessage(msg);   }   }catch (IOException e){   e.printstacktrace();   }  }  }.start();  //由于子线程中没有默认初始化Looper,要在子线程中创建Handler,需要自己写  Looper.prepare();  revHandler = new Handler() {  @OverrIDe  public voID handleMessage(Message msg) {   if (msg.what == 1) {   try {    mOutputStream.write((msg.obj.toString() + "\r\n").getBytes("utf-8"));   } catch (IOException e) {    e.printstacktrace();   }   }  }  };  Looper.loop(); } catch (IOException e) {  e.printstacktrace();  Log.d("xjj",""); } }}

activity_main

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:ID="@+ID/activity_main" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:padding="@dimen/activity_vertical_margin" androID:orIEntation="vertical" > <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:orIEntation="horizontal"> <EditText  androID:ID="@+ID/et_main"  androID:layout_wIDth="0dp"  androID:layout_height="wrap_content"  androID:layout_weight="1"/> <button  androID:ID="@+ID/btn_main"  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content"  androID:text="@string/send"/> </linearLayout> <TextVIEw androID:ID="@+ID/tv_main" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" /></linearLayout>

服务器:

MySever

import java.io.IOException;import java.net.ServerSocket;import java.net.socket;import java.util.ArrayList;public class MySever { public static ArrayList<Socket> socketList = new ArrayList<Socket>(); public static String content=""; public static voID main(String[] args) throws IOException { //建立ServerSocket ServerSocket ss = new ServerSocket(30003); //不断接收此端口的socket,并存储到socketList中 //并且为每一个socket开启一个线程,用于接收信息 while (true) {  Socket s = ss.accept();  System.out.println("connect success!");  socketList.add(s);  new Thread(new ServerThread(s)).start(); } }}

SeverThread

import java.io.BufferedReader;import java.io.IOException;import java.io.inputStreamReader;import java.io.OutputStream;import java.io.UnsupportedEnCodingException;import java.net.socket;import java.net.socketException;import java.util.Iterator;public class ServerThread implements Runnable { private Socket mSocket = null; private BufferedReader mBufferedReader = null; // 构造函数中接收socket并且初始化BufferedReader public ServerThread(Socket socket)   throws UnsupportedEnCodingException,IOException { mSocket = socket; mBufferedReader = new BufferedReader(  new inputStreamReader(mSocket.getinputStream(),"utf-8")); } @OverrIDe public voID run() { // Todo auto-generated method stub try {  String content = null;  //循环接收来自此客户端的消息  //如果接收不到了,表面已经断开,就将此客户端从socketList中移除  while ((content = mBufferedReader.readline()) != null) {  System.out.println(content);  //向连接中的每个客户端发送数据  //如果异常,说明断开,就将该条目从socketList中移除  for (Iterator<Socket> it = MySever.socketList.iterator();    it.hasNext();) {   Socket s = it.next();   try {   OutputStream os = s.getoutputStream();   os.write((content + "\n").getBytes("utf-8"));   } catch (SocketException e) {   e.printstacktrace();   it.remove();   }  }  } } catch (IOException e) {  e.printstacktrace();  MySever.socketList.remove(mSocket); } }}

源码地址:android socket聊天室

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的android socket聊天室功能实现全部内容,希望文章能够帮你解决android socket聊天室功能实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1146533.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存