android使用Socket通信实现多人聊天应用

 更新时间:2018年03月30日 14:56:53   作者:其实我叫孟小贤  
这篇文章主要为大家详细介绍了android使用Socket通信实现多人聊天应用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

使用Socket实现多人聊天应用,供大家参考,具体内容如下

 

在讲scoket通信器先可以先了解一下网络协议

手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。可以将网络协议分为四层,从高到低依次为:应用层、传输层、网络层、链路层。

两种Socket类型的基本通信

TCP是一个可靠的、面向连接的协议。它可以保证数据从连接的一方传递到另一方,并且发送数据的顺序和所接收数据的顺序一致。当应用程序需要一个可靠的、点对点的连接时,可以使用TCP。

UDP是一种不可靠的通信协议,没有检测错误的机制,也不重发丢失的数据。接收到的数据包的顺序可能与发送的数据包的顺序不一致。采用UDP进行通信时,事先不需要建立连接。而采用TCP进行通信时,首先要建立一个连接。TCP的通信质量比UDP高,UDP的开销比TCP小。

 

这里我们以TCP协议为主

其实android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信。两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。通过建立socket连接,可为通信双方的数据传输传提供通道。socket的主要特点有数据丢失率低,使用简单且易于移植。

Socket套接字概念

 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

先看一下TCP通信的步骤:

建立Socket连接

• 连接过程分为三个步骤:

–服务端监听

–客户端请求

–连接确认

(多线程机制,各个客户端和服务器之间的通信)

–服务端:ServerSocket

–客户端:Socket

–信息传输:

• 发送信息getoutputsream()   write();

• 接收信息getinputstream()    read(); 

案例:

使用TCP协议通信

 java服务端,此时是使用java做服务端

ScoketDemo .java

package scoket.activity; 
 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.UnsupportedEncodingException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 
 
public class ScoketDemo { 
 public static List<Socket> clients = new ArrayList<Socket>();// 创建一个集合存放所有的客户端 
 
 /** 
  * @param args 
  * @throws IOException 
  */ 
 public static void main(String[] args) throws IOException { 
  // TODO Auto-generated method stub 
  ServerSocket ss; 
  while (true) { 
   ss = new ServerSocket(2019); 
   Socket s = ss.accept();// 使服务端处于监听状态 
 
   clients.add(s); 
   // 为每一个客户端开设一个单个线程 
   new ChatThread(s).start(); 
 
   // OutputStream os=client.getOutputStream(); 
   // os.write("Nice to meet you!".getBytes("utf-8")); 
   // os.close();//网络编程流的关闭是按栈的方式关闭的 
   // client.close(); 
  } 
  // No enclosing instance of type ScoketDemo is accessible. Must qualify 
  // the allocation 
  // with an enclosing instance of type 
  // ScoketDemo (e.g. x.new A() where x is an instance of ScoketDemo). 
 } 
 
 public static class ChatThread extends Thread { 
 
  Socket client; 
  BufferedReader br; 
 
  public ChatThread(Socket c) { 
   super(); 
   this.client = c; 
 
   try { 
    br = new BufferedReader(new InputStreamReader( 
      client.getInputStream(), "UTF-8"));// 将客户端对象封装一下 
   } catch (UnsupportedEncodingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
 
  } 
 
  @Override 
  public void run() { 
   // TODO Auto-generated method stub 
   super.run(); 
   String content = null; 
   // 获取客户端传递过来的数据 
   try { 
    while ((content = br.readLine()) != null) { 
     // 再将服务端的数据返回给客户端 
     OutputStream os = client.getOutputStream(); 
     os.write(content.getBytes("utf-8")); 
    } 
   } catch (UnsupportedEncodingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
  } 
 
 } 
} 

android客户端

ChatScoketDemoActivity.java

package com.scoket.activity; 
 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.Socket; 
import java.net.UnknownHostException; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
 
public class ChatScoketDemoActivity extends Activity implements OnClickListener { 
 /** Called when the activity is first created. */ 
 private EditText name, setence, show; 
 private Button btn; 
 Socket client; 
 Handler myHandler = new Handler() { 
  public void handleMessage(android.os.Message msg) { 
   if (msg.what==123) { 
    String str = show.getText().toString(); 
    show.setText(str +"\n"+ msg.getData().getString("chat")); 
   } 
    
  }; 
 }; 
 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main); 
  btn = (Button) findViewById(R.id.button1); 
  name = (EditText) findViewById(R.id.name); 
  setence = (EditText) findViewById(R.id.setence); 
  show = (EditText) findViewById(R.id.show); 
 
  btn.setOnClickListener(this); 
  new Thread(new Runnable() { 
 
   @Override 
   public void run() { 
    // TODO Auto-generated method stub 
    try { 
     client = new Socket("172.20.52.26", 2019);// 网络访问最好放在线程中 
     new chatThread(client).start();// 启动子线程 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
   } 
  }).start(); 
   
 } 
 
 @Override 
 public void onClick(View arg0) { 
  // TODO Auto-generated method stub 
  String s1 = name.getText().toString(); 
  String s2 = setence.getText().toString(); 
  String s3 = s1 + ":" + s2+"\n"; 
  if (client != null) { 
   try { 
    client.getOutputStream().write(s3.getBytes("utf-8"));// 获取从客户端得到的数据 
   } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
  } //setence.setText("");//相当于刷新 
 } 
 
 class chatThread extends Thread { 
  Socket s; 
 
  public chatThread(Socket s) { 
   super(); 
   this.s = s; 
  } 
 
  @Override 
  public void run() { 
 
   try { 
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
    while (true) { 
     String content = br.readLine(); 
     if (content != null) { 
      Bundle bundle = new Bundle(); 
      bundle.putString("chat", content); 
      Message msg = new Message(); 
      msg.setData(bundle); 
      msg.what=123; 
      myHandler.sendMessage(msg); 
     } 
 
    } 
   } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
  } 
 
 } 
} 

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

相关文章

  • 解决Android studio 3.6.1 出现Cause: unable to find valid certification path to requested target 报错的问题

    解决Android studio 3.6.1 出现Cause: unable to find valid certifi

    这篇文章主要介绍了Android studio 3.6.1 出现Cause: unable to find valid certification path to requested target 报错的问题及解决方法,需要的朋友可以参考下
    2020-03-03
  • Android自定义选项卡切换效果

    Android自定义选项卡切换效果

    这篇文章主要为大家详细介绍了Android自定义选项卡切换效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Android 录音与播放功能的简单实例

    Android 录音与播放功能的简单实例

    这篇文章主要介绍了 Android 录音与播放功能的简单实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • Android实现局部模糊效果

    Android实现局部模糊效果

    这篇文章主要为大家详细介绍了Android实现局部模糊效果,帮助大家实现模糊或者毛玻璃效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • android 支持的语言列表(汇总)

    android 支持的语言列表(汇总)

    本篇文章是对android支持的语言进行了部分汇总,需要的朋友参考下
    2013-06-06
  • 刷新Activity中的scrollview示例(局部ui刷新)

    刷新Activity中的scrollview示例(局部ui刷新)

    代码很简单,但是很实用,适合在一个Activity中要刷新局部的UI,比如在扫描一维码的时候,要把每次扫描的结果都显示在界面上
    2014-01-01
  • Android RecyclerView 复用错乱通用解法详解

    Android RecyclerView 复用错乱通用解法详解

    本篇文章主要介绍了Android RecyclerView 复用错乱通用解法详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Adnroid打造通用的带进度条的WebView

    Adnroid打造通用的带进度条的WebView

    这篇文章主要为大家详细介绍了Adnroid打造通用的带进度条的WebView的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • ListView的Adapter使用 之 初学ArrayAdapter String

    ListView的Adapter使用 之 初学ArrayAdapter String

    ListView是Android中经常会使用的东西,绑定数据对于初学者来说,尤其是刚接触编程的人来说,往往会觉得很难理解,我上大二的时候学的java,但是基本上相当于没有学,什么都没写过,真正接触编程就是开始上手学android,把这些记录下来,自己可以回头看下,也可以让新手更好的理解
    2013-06-06
  • Android 实现圆角图片的简单实例

    Android 实现圆角图片的简单实例

    这篇文章主要介绍了Android 实现圆角图片的简单实例的相关资料,Android 圆角图片的实现形式,包括用第三方、也有系统,需要的朋友可以参考下
    2017-07-07

最新评论