Android开发之Socket通信传输简单示例

发布时间 - 2026-01-11 03:02:02    点击率:

本文实例讲述了Android Socket通信传输实现方法。分享给大家供大家参考,具体如下:

1.开篇简介

Socket本质上就是Java封装了传输层上的TCP协议(注:UDP用的是DatagramSocket类)。要实现Socket的传输,需要构建客户端和服务器端。另外,传输的数据可以是字符串和字节。字符串传输主要用于简单的应用,比较复杂的应用(比如Java和C++进行通信),往往需要构建自己的应用层规则(类似于应用层协议),并用字节来传输。

2.基于字符串传输的Socket案例

1)服务器端代码(基于控制台的应用程序,模拟)

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.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
  private static final int PORT = 9999;
  private List<Socket> mList = new ArrayList<Socket>();
  private ServerSocket server = null;
  private ExecutorService mExecutorService = null; //thread pool
  public static void main(String[] args) {
    new Main();
  }
  public Main() {
    try {
      server = new ServerSocket(PORT);
      mExecutorService = Executors.newCachedThreadPool(); //create a thread pool
      System.out.println("服务器已启动...");
      Socket client = null;
      while(true) {
        client = server.accept();
        //把客户端放入客户端集合中
        mList.add(client);
        mExecutorService.execute(new Service(client)); //start a new thread to handle the connection
      }
    }catch (Exception e) {
      e.printStackTrace();
    }
  }
  class Service implements Runnable {
      private Socket socket;
      private BufferedReader in = null;
      private String msg = "";
      public Service(Socket socket) {
        this.socket = socket;
        try {
          in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
          //客户端只要一连到服务器,便向客户端发送下面的信息。
          msg = "服务器地址:" +this.socket.getInetAddress() + "come toal:"
            +mList.size()+"(服务器发送)";
          this.sendmsg();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      @Override
      public void run() {
        try {
          while(true) {
            if((msg = in.readLine())!= null) {
              //当客户端发送的信息为:exit时,关闭连接
              if(msg.equals("exit")) {
                System.out.println("ssssssss");
                mList.remove(socket);
                in.close();
                msg = "user:" + socket.getInetAddress()
                  + "exit total:" + mList.size();
                socket.close();
                this.sendmsg();
                break;
                //接收客户端发过来的信息msg,然后发送给客户端。
              } else {
                msg = socket.getInetAddress() + ":" + msg+"(服务器发送)";
                this.sendmsg();
              }
            }
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
     /**
      * 循环遍历客户端集合,给每个客户端都发送信息。
      */
      public void sendmsg() {
        System.out.println(msg);
        int num =mList.size();
        for (int index = 0; index < num; index ++) {
          Socket mSocket = mList.get(index);
          PrintWriter pout = null;
          try {
            pout = new PrintWriter(new BufferedWriter(
                new OutputStreamWriter(mSocket.getOutputStream())),true);
            pout.println(msg);
          }catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    }
}

2)Android客户端代码

package com.amaker.socket;
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;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class SocketDemo extends Activity implements Runnable {
  private TextView tv_msg = null;
  private EditText ed_msg = null;
  private Button btn_send = null;
  // private Button btn_login = null;
  private static final String HOST = "10.0.2.2";
  private static final int PORT = 9999;
  private Socket socket = null;
  private BufferedReader in = null;
  private PrintWriter out = null;
  private String content = "";
  //接收线程发送过来信息,并用TextView显示
  public Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      tv_msg.setText(content);
    }
  };
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tv_msg = (TextView) findViewById(R.id.TextView);
    ed_msg = (EditText) findViewById(R.id.EditText01);
    btn_send = (Button) findViewById(R.id.Button02);
    try {
      socket = new Socket(HOST, PORT);
      in = new BufferedReader(new InputStreamReader(socket
          .getInputStream()));
      out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
          socket.getOutputStream())), true);
    } catch (IOException ex) {
      ex.printStackTrace();
      ShowDialog("login exception" + ex.getMessage());
    }
    btn_send.setOnClickListener(new Button.OnClickListener() {
      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        String msg = ed_msg.getText().toString();
        if (socket.isConnected()) {
          if (!socket.isOutputShutdown()) {
            out.println(msg);
          }
        }
      }
    });
    //启动线程,接收服务器发送过来的数据
    new Thread(SocketDemo.this).start();
  }
  /**
   * 如果连接出现异常,弹出AlertDialog!
   */
  public void ShowDialog(String msg) {
    new AlertDialog.Builder(this).setTitle("notification").setMessage(msg)
        .setPositiveButton("ok", new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
          }
        }).show();
  }
  /**
   * 读取服务器发来的信息,并通过Handler发给UI线程
   */
  public void run() {
    try {
      while (true) {
        if (!socket.isClosed()) {
          if (socket.isConnected()) {
            if (!socket.isInputShutdown()) {
              if ((content = in.readLine()) != null) {
                content += "\n";
                mHandler.sendMessage(mHandler.obtainMessage());
              } else {
              }
            }
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

解析:除了isClose方法,Socket类还有一个isConnected方法来判断Socket对象是否连接成功。  看到这个名字,也许读者会产生误解。  其实isConnected方法所判断的并不是Socket对象的当前连接状态,  而是Socket对象是否曾经连接成功过,如果成功连接过,即使现在isClose返回true, isConnected仍然返回true。因此,要判断当前的Socket对象是否处于连接状态, 必须同时使用isClose和isConnected方法, 即只有当isClose返回false,isConnected返回true的时候Socket对象才处于连接状态。 虽然在大多数的时候可以直接使用Socket类或输入输出流的close方法关闭网络连接,但有时我们只希望关闭OutputStreamInputStream,而在关闭输入输出流的同时,并不关闭网络连接。这就需要用到Socket类的另外两个方法:shutdownInputshutdownOutput,这两个方法只关闭相应的输入、输出流,而它们并没有同时关闭网络连接的功能。和isClosed、isConnected方法一样,Socket类也提供了两个方法来判断Socket对象的输入、输出流是否被关闭,这两个方法是isInputShutdown()isOutputShutdown()。 shutdownInput和shutdownOutput并不影响Socket对象的状态。

2.基于字节的传输

基于字节传输的时候,只需要把相应的字符串和整数等类型转换为对应的网络字节进行传输即可。具体关于如何把其转换为网络字节,请参《Java整型数与网络字节序byte[]数组转换关系详解》。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android通信方式总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android多媒体操作技巧汇总(音频,视频,录音等)》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。


# Android  # Socket  # 通信传输  # 详解Android 基于TCP和UDP协议的Socket通信  # Android使用WebSocket实现多人游戏  # 详解OkSocket与Android的简单使用  # android基于socket的局域网内服务器与客户端加密通信  # android socket聊天室功能实现  # SpringBoot webSocket实现发送广播、点对点消息和Android接收  # Android中Socket大文件断点上传示例  # android Socket实现简单聊天功能以及文件传输  # 详解Android使用Socket对大文件进行加密传输  # 详解Android 通过Socket 和服务器通讯(附demo)  # Android Socket接口实现即时通讯实例代码  # Android完整Socket解决方案  # 客户端  # 这两个  # 转换为  # 方法来  # 自己的  # 的是  # 进阶  # 应用层  # 相关内容  # 遍历  # 只需  # 而在  # 感兴趣  # 要把  # 这就  # 给大家  # 弹出  # 还有一个  # 可以直接  # 更多关于 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  Laravel如何使用查询构建器?(Query Builder高级用法)  js实现点击每个li节点,都弹出其文本值及修改  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  如何在云主机快速搭建网站站点?  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】  Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性  Laravel API资源类怎么用_Laravel API Resource数据转换  高防服务器租用如何选择配置与防御等级?  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  如何快速搭建高效服务器建站系统?  如何自定义建站之星网站的导航菜单样式?  如何在建站之星绑定自定义域名?  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Android实现代码画虚线边框背景效果  如何快速生成凡客建站的专业级图册?  js代码实现下拉菜单【推荐】  微信h5制作网站有哪些,免费微信H5页面制作工具?  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何生成腾讯云建站专用兑换码?  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  如何用腾讯建站主机快速创建免费网站?  如何在阿里云虚拟主机上快速搭建个人网站?  详解MySQL数据库的安装与密码配置  Laravel如何保护应用免受CSRF攻击?(原理和示例)  如何快速完成中国万网建站详细流程?  如何在万网自助建站平台快速创建网站?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践  Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  微信小程序 input输入框控件详解及实例(多种示例)  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  C语言设计一个闪闪的圣诞树  如何快速生成可下载的建站源码工具?  深圳网站制作培训,深圳哪些招聘网站比较好?  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  Laravel如何生成URL和重定向?(路由助手函数)  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  javascript中的try catch异常捕获机制用法分析  如何快速搭建高效简练网站?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  英语简历制作免费网站推荐,如何将简历翻译成英文?  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  JavaScript模板引擎Template.js使用详解