Android实现C/S聊天室

Java中能接受其他通信实体链接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket链接,如果没有链接,它将一直等待。如果接收到一个客户端Socket的连接请求,ServerSocket的accept()方法将返回一个与客户端Socket对应的Socket(每个TCP连接有两个Socket),否则该方法将一直阻塞,线程也被阻塞。

服务端思路:服务端应该包含多个线程,每个Socket对应一个线程,这个线程负责读取该Socket对应输入流的数据(从客户端发送过来的数据),并将读到的数据向每个Socket输出流发送一次(将一个客户端发送过来的数据“广播”给其他客户端)。

服务端代码:

//服务端主类
public class MyServer
{
  public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<Socket>());
  public static void main(String[] args) throws IOException
  {
    ServerSocket ss = new ServerSocket(30000);
    while (true)
    {
      //此行代码会阻塞,将一直等待别人的连接
      Socket s = ss.accept();
      socketList.add(s);
      //每当客户端连接后启动一个ServerThread线程为该客户端服务
      new Thread(new ServerThread(s)).start();
    }
  }
}
public class ServerThread implements Runnable
{
  //定义当前线程所处理的Socket
  Socket s = null;
  //该线程所处理的Socket对应的输入流
  BufferedReader br = null;
  public ServerThread(Socket s) throws IOException
  {
    this.s = s;
    //初始化该Socket对应的输入流
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
  }

  @Override
  public void run()
  {
    try
    {
      String content = null;
      //采用循环不断地从Socket中读取客户端发送来的数据
      while ((content = readFromClient()) != null)
      {
        //遍历socketList中的每个Socket
        //将读到的内容向每个Socket发送一次
        for (Socket s : MyServer.socketList)
        {
          PrintStream ps = new PrintStream(s.getOutputStream());
          ps.println(content);
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  //定义读取客户端数据的方法
  private String readFromClient()
  {
    try
    {
      return br.readLine();
    }
    //如果捕获到异常,则表明该Socket对应的客户端已经关闭
    catch (IOException e)
    {
      //删除该Socket
      MyServer.socketList.remove(s);
    }
    return null;
  }
}

客户端思路:将用户输入的数据写入Socket对应的输入流中;开启一个子线程读取Socket对应输入流中的数据(从服务端发送过来的数据),并通过Handler将读取的数据发送到主线程来更新UI。

//用户界面Activity
public class MainActivity extends Activity
{
  private EditText mReceiverMsg;
  private Button mSendBtn;
  private EditText mSendMsg;
  Handler handler = new Handler()
  {
    @Override
    public void handleMessage(Message msg)
    {
      Log.d("mainActivity" , "okk");
      mReceiverMsg.append(msg.obj.toString());
    }
  };
  private Socket s;
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    initView();
    initSocket();
    mSendBtn.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        sendData();
      }
    });
  }

  private void initSocket()
  {
    new Thread()
    {
      @Override
      public void run()
      {
        try
        {
          s = new Socket("192.168.1.101" , 30000);
          new Thread(new ClientThread(s , handler)).start();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
      }
    }.start();
  }

  private void initView()
  {
    mReceiverMsg = (EditText) findViewById(R.id.receiver_message);
    mSendMsg = (EditText) findViewById(R.id.send_message);
    mSendBtn = (Button) findViewById(R.id.send_button);
  }

  private void sendData()
  {
    try
    {
      //获取该Socket对应的输出流
      PrintStream ps = new PrintStream(s.getOutputStream());
      if (TextUtils.isEmpty(mSendMsg.getText()))
      {
        Toast.makeText(this , "请输入信息" , Toast.LENGTH_LONG).show();
        return;
      }
      ps.println(mSendMsg.getText().toString());
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}
public class ClientThread implements Runnable
{
  //该线程负责处理的Socket
  private Socket ss;
  //该线程所处理的Socket对应的输入流
  BufferedReader br = null;
  Handler handler;
  public ClientThread(Socket s , Handler handler) throws IOException
  {
    this.ss = s;
    this.handler = handler;
    br = new BufferedReader(new InputStreamReader(ss.getInputStream()));
  }

  @Override
  public void run()
  {
    try
    {
      String content = null;
      while ((content = br.readLine()) != null)
      {
        Message msg = new Message();
        msg.obj = content;
        handler.sendMessage(msg);
      }

    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}

先运行上面程序中的MyServer类,该类运行只是作为服务端。再启动多个模拟器,运行安装客户端的程序作为多个客户端,然后可以再任何一个客户端通过Edit输入一些内容,点击发送就可以在任何一个客户端看到刚刚输入的内容。

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

(0)

相关推荐

  • Android 基于Socket的聊天室实例

    Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信. Client A  发信息给 Client B ,  A的信息首先发送信息到服务器Server ,Server接受到信息后再把A的信息广播发送给所有的Clients 首先我们要在服务器建立一个ServerSocket ,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待

  • Android使用多线程进行网络聊天室通信

    TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信了.Java对基于TCP协议的网络通信提供了良好的封装,Java使用Socket对象来代表两端通信接口,并通过Socket产生IO流来进行网络通信. 下面的程序Demo是实现一个简单的C/S聊天室的应用,每个客户端该包含两条线程:一条负责生成主界面,响应用户动作,并将用户输入的数据写入Socket对应的输出流中:另一条

  • android socket聊天室功能实现

    前提概要 笔者很久之前其实就已经学习过了socket,当然也是用socket做过了聊天室,但是觉得此知识点比较一般,并无特别难的技术点,于是也并未深究. 然而近期一个项目中对socket的使用却让笔者感觉socket强大无比,可以实现诸多功能. 个人Socket体验 项目主要有关智能家居,需要实现多台手机同时对灯进行操作(开或者关),主要需要实现以下几点: 1.进入界面时获取所有灯的状态. 2.一台手机改变了灯的状态,其他的手机上可以有所显示. 3.硬件上改变了灯的状态(手动开关灯),所有手机上

  • Android中基于XMPP协议实现IM聊天程序与多人聊天室

    简单的IM聊天程序 由于项目需要做一个基于XMPP协议的Android通讯软件.故开始研究XMPP. XMPP协议采用的是客户端-服务器架构,所有从一个客户端发到另一个客户端的消息和数据都必须经过XMPP服务器转发,而且支持服务器间DNS的路由,也就是说可以构建服务器集群,使不同的 服务器下的客户端也可以通信,XMPP的前身是一个开源组织制定的网络通信协议--Jabber,XMPP的核心是在网络上分片段发送XML流的协议,这个协议是XMPP的即时通讯指令的传递手段.       为了防止服务器间

  • Android使用Websocket实现聊天室

    最近的项目中要实现一个聊天的功能,类似于斗鱼TV的聊天室功能,与服务器端人商量后决定用WebSocket来做,但是在这之前我只知道Socket但是听都没有听过WebSocket,但是查看了相关的材料以后发现实现一个聊天室其实是很简单的!下面我们先来看看WebSocket. Autobahn|Android 是由Autobahn开发一个开源的Java/Android网络库,实现了WebSocket协议和Web应用程序消息传输协议来创建本地移动的WebSocket/ WAMP的客服端. WebSoc

  • Android Socket通信实现简单聊天室

    socket通信是基于底层TCP/IP协议实现的.这种服务端不需要任何的配置文件和tomcat就可以完成服务端的发布,使用纯java代码实现通信.socket是对TCP/IP的封装调用,本身并不是一种协议,我们通过socket来调用协议来跟服务端进行通信和数据的传输.socket就像客户端与服务端之间的一条信息通道,每一个不同的客户端都会建立一个独立的socket,双方都没有关闭连接的话,连接-也就是建立好的这条socket通道将一直保持,服务端要跟那一个客户端通信只需要找到对应的socket对

  • Android编写简单的聊天室应用

    最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能.主要技术点就是怎样把表情图片放到textview等Ui控件中展示.这里废话不多说,下面是效果图: 这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录drawable中而所有的资源文件都是R这个类来管理,所以我们可以利用正则表达式找出图片id包装成ImageSpan然后把ImageSpan放到SpannableString中,最后把SpannableString放入edittext中,下面是源码: pack

  • Android实现简单C/S聊天室应用

    Android的网络应用:简单的C/S聊天室,供大家参考,具体内容如下 服务器端:提供两个类 创建ServerSocket监听的主类:MyServer.java 负责处理每个Socket通信的线程类:ServerThread.java 客户端:是一个Android应用程序 ==>MultiThreadClient 界面提供两个文本框和一个发送按钮 Activity通过Handler来处理来自子线程的消息 客户端需要一个子线程负责读取来自网络的数据 项目效果: 服务器端代码: MyServer.j

  • Android实现C/S聊天室

    Java中能接受其他通信实体链接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket链接,如果没有链接,它将一直等待.如果接收到一个客户端Socket的连接请求,ServerSocket的accept()方法将返回一个与客户端Socket对应的Socket(每个TCP连接有两个Socket),否则该方法将一直阻塞,线程也被阻塞. 服务端思路:服务端应该包含多个线程,每个Socket对应一个线程,这个线程负责读取该Socket对应输入流的数据(从客户端发

  • Android 基于Socket的聊天应用实例(二)

    前言 很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的一个类似现在多数聊天软件的冒泡聊天APP.全部功能都是自己的想法,对于现在市面上成功的例子是怎么实现的,我还不了解.所以读者可只做参考学习,也可以分享您的案例给我. 功能 一对一聊天,非聊天室 好友列表 好友在线,离线状态(实时更新) 冒泡实时聊天窗口 发送离线信息 基本原理 之前的聊天室原理

  • 使用WebSocket实现即时通讯(一个群聊的聊天室)

    随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据. 传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据:这种客户端是主动方,服务端是被动方的传统Web模式对于信息变化不频繁的Web应用来说造成的麻烦

随机推荐