专栏首页Android知识点总结3--安卓网络编程之Socket编程

3--安卓网络编程之Socket编程

实现场景:手机A作为客户端,手机B作为服务端,通过Socket实现信息交互与处理。 如下图:客户端通过ip和端口连接服务器,客户端发送hello,服务端接收后,处理成大写发送给客户端,通过Toast显示 虽然是个简单的测试,但基本涵盖了Socket编程的所有基础知识

页面布局

socket编程1png

服务端显示效果

打开服务以及有设备加入时,界面上的反应

socket编程2.png

socket编程.png

一、服务端实现

1.服务端界面:TCPServerActivity.java

1.通过ServerSocket开启服务 2.将连接的客户端显示在服务端界面 3.为该客户端开启服务线程

case R.id.id_btn_start_server://开启服务
    new Thread(() -> {
        try {
            //1.开启服务器
            ServerSocket serverSocket = new ServerSocket(8080);
            runOnUiThread(() -> mIdTvLink.setText("服务已开启"));
            mJoinRunnable = new JoinRunnable(serverSocket);
            //2.将连接的客户端显示在服务端界面
            mJoinRunnable.setOnConnListener(ip -> runOnUiThread(() -> {
                mIdTvLink.append("\n" + ip + "已连接");
            }));
            //3.为该客户端开启服务线程
            new Thread(mJoinRunnable).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start();
    break;
case R.id.id_btn_close_server://关闭服务
    if (mJoinRunnable != null) {
        mIdTvLink.setText("服务未开启");
        mJoinRunnable.close();
    }
    break;
2.JoinRunnable:每次客户端加入时创建的线程

1.通过服务端ServerSocket获取Socket对象 2.获取连接的客户端ip,并设置连接时的回调监听 3.通过Socket获取输入I流,读取客户端的信息 4.通过Socket获取输出O流,向客户端发送信息 5.进行IO流操作

/**
 * 作者:张风捷特烈<br/>
 * 时间:2018/10/14 0014:8:01<br/>
 * 邮箱:1981462002@qq.com<br/>
 * 说明:每次客户端加入时创建的线程
 */
public class JoinRunnable implements Runnable {

    private ServerSocket mServerSocket;//ServerSocket对象
    private Socket mSocket;//Socket对象

    public JoinRunnable(ServerSocket serverSocket) {
        mServerSocket = serverSocket;
    }

    @Override
    public void run() {
        InputStream is = null;
        OutputStream os = null;
        try {
            //1.通过服务端ServerSocket获取Socket对象
            mSocket = mServerSocket.accept();
            //2.获取连接的客户端ip,并设置连接时的回调监听
            String ip = mSocket.getInetAddress().getHostAddress();
            if (mOnConnListener != null) {
                mOnConnListener.conn(ip);
            }
            //3.通过Socket获取输入I流,读取客户端的信息
            is = mSocket.getInputStream();
            //4.通过Socket获取输出O流,向客户端发送信息
            os = mSocket.getOutputStream();
            //5.IO操作
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = is.read(buf)) != -1) {
                String msg = new String(buf, 0, len).toUpperCase();
                //将读出来的信息进行操作后返回给客户端
                os.write(("服务端发来信息:" + msg).getBytes());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭客户端连接
     */
    public void close() {
        try {
            mServerSocket.close();
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //客户端连接时的监听
    public interface OnConnListener {
        void conn(String ip);
    }

    private OnConnListener mOnConnListener;

    public void setOnConnListener(OnConnListener onConnListener) {
        mOnConnListener = onConnListener;
    }
}

二、客户端页:

@OnClick({R.id.id_btn_send, R.id.id_btn_setip})
public void onViewClicked(View view) {
    switch (view.getId()) {
        case R.id.id_btn_setip:
            //通过ip和端口连接服务端
            new Thread(() -> connServer(mIdEtIp.getText().toString(), 8080)).start();
            break;
        case R.id.id_btn_send:
            //将键盘输入内容发送给服务端
            mPwOut.println(mIdTcp.getText());
            break;
    }
}

/**
 * 通过ip和端口连接服务端核心代码
 *
 * @param ip   ip地址
 * @param port 端口
 */
private void connServer(String ip, int port) {
    try {
        //1.创建客户端Socket对象(ip,端口)
        mSocket = new Socket(ip, port);
        //2.通过socket对象获取字节输出流,并包装成PrintWriter----用于发送给服务端数据
        mPwOut = new PrintWriter(mSocket.getOutputStream(), true);
        //3.通过socket对象获取字节输出流
        InputStream is = mSocket.getInputStream();
        int len = 0;
        byte[] buf = new byte[1024];
        while ((len = is.read(buf)) != -1) {
            msg = new String(buf, 0, len).toUpperCase();
            runOnUiThread(() -> ToastUtil.showAtOnce(TCPClientActivity.this, msg));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mSocket != null) {
        try {
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

后记:捷文规范

1.本文成长记录及勘误表

项目源码

日期

备注

V0.1--无

2018-10-15

2--安卓网络编程之http协议简介+小案例引入

2.更多关于我

笔名

QQ

微信

爱好

张风捷特烈

1981462002

zdl1994328

语言

我的github

我的简书

我的CSDN

个人网站

3.声明

1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringBoot-15-之整合MyBatis-注解篇+分页

    张风捷特烈
  • [Flutter必备]-StatefulWidget的打开方式

    张风捷特烈
  • 2-AVI--Fragment生命周期测试

    张风捷特烈
  • Netty 系列七(那些开箱即用的 ChannelHandler).

        Netty 为许多通用协议提供了编解码器和处理器,几乎可以开箱即用, 这减少了你在那些相当繁琐的事务上本来会花费的时间与精力。另外,这篇文章中,就不涉及...

    JMCui
  • SQN with Lunar landing challenge

    Our team combine SAC algorithm and DQN method gave a useful way to solve the...

    用户1908973
  • 蓝桥杯 基础练习 数的读法

      Tom教授正在给研究生讲授一门关于基因的课程,有一件事情让他颇为头疼:一条染色体上有成千上万个碱基对,它们从0开始编号,到几百万,几千万,甚至上亿。   比...

    Meng小羽
  • 【asp.net core】实现动态 Web API

    远程工作已经一个月了,最近也算是比较闲,每天早上起床打个卡,快速弄完当天要做的工作之后就快乐摸鱼去了。之前在用 ABP 框架(旧版)的时候就觉得应用服务层写起来...

    李明成
  • Dijkstra双栈表达式求值算法

    SuperHeroes
  • 关于架构思想的看法

    目前开发中用到的主流思想主要是MVC 、 MVP、 MVVM这三种思想。前端用的MVVM,后端用的MVC,安卓用的是MVP。具体的每一种使用后面做详细讲解。

    AWeiLoveAndroid
  • 【陆勤践行】DataSchool 推荐的数据科学资源

    Blogs Simply Statistics1: Written by the Biostatistics professors at Johns Hopki...

    陆勤_数据人网

扫码关注云+社区

领取腾讯云代金券