写点什么

Android Socket 使用详解,android 开发入门与实战作者

用户头像
Android架构
关注
发布于: 57 分钟前

// 断开 客户端发送到服务器 的连接,即关闭输出流对象 OutputStream


br.close();// 断开 服务器发送到客户端 的连接,即关闭输入流读取器对象 BufferedReader


socket.close();// 最终关闭整个 Socket 连接


[](

)6. 具体实例

  • 实例 Demo 代码包括:客户端 & 服务器

  • 本文着重讲解客户端,服务器仅采用最简单的写法进行展示

[](

)6.1 客户端 实现


步骤 1:加入网络权限


<uses-permission android:name="android.permission.INTERNET" />


步骤 2:主布局界面设置


包括创建 Socket 连接、客户端 & 服务器通信的按钮


<Buttonandroid:id="@+id/connect"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="connect" />


<Buttonandroid:id="@+id/disconnect"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="disconnect" />


<TextViewandroid:id="@+id/receive_message"android:layout_width="match_parent"android:layout_height="wrap_content" />


<Buttonandroid:id="@+id/Receive"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Receive from message" />


<EditTextandroid:id="@+id/edit"android:layout_width="match_parent"android:layout_height="wrap_content" />


<Buttonandroid:id="@+id/send"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="send"/>


步骤 3:创建 Socket 连接、客户端 & 服务器通信


具体请看注释


MainActivity.java


package scut.carson_ho.socket_carson;


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;


import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;


public class MainActivity extends AppCompatActivity {


/**


  • 主 变量*/


// 主线程 Handler// 用于将从服务器获取的消息显示出来 private Handler mMainHandler;


// Socket 变量 private Socket socket;


// 线程池// 为了方便展示,此处直接采用线程池进行线程管理,而没有一个个开线程 private ExecutorService mThreadPool;


/**


  • 接收服务器消息 变量*/// 输入流对象 InputStream is;


// 输入流读取器对象 InputStreamReader isr ;BufferedReader br ;


// 接收服务器发送过来的消息 String response;


/**


  • 发送消息到服务器 变量*/// 输出流对象 OutputStream outputStream;


/**


  • 按钮 变量*/


// 连接 断开连接 发送数据到服务器 的按钮变量 private Button btnConnect, btnDisconnect, btnSend;


// 显示接收服务器消息 按钮 private TextView Receive,receive_message;


// 输入需要发送的消息 输入框 private EditText mEdit;


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);


/**


  • 初始化操作*/


// 初始化所有按钮 btnConnect = (Bu


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


tton) findViewById(R.id.connect);btnDisconnect = (Button) findViewById(R.id.disconnect);btnSend = (Button) findViewById(R.id.send);mEdit = (EditText) findViewById(R.id.edit);receive_message = (TextView) findViewById(R.id.receive_message);Receive = (Button) findViewById(R.id.Receive);


// 初始化线程池 mThreadPool = Executors.newCachedThreadPool();


// 实例化主线程,用于更新接收过来的消息 mMainHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0:receive_message.setText(response);break;}}};


/**


  • 创建客户端 & 服务器的连接*/btnConnect.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {


// 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() {@Overridepublic void run() {


try {


// 创建 Socket 对象 & 指定服务端的 IP 及 端口号 socket = new Socket("192.168.1.172", 8989);


// 判断客户端和服务器是否连接成功 System.out.println(socket.isConnected());


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


}});


}});


/**


  • 接收 服务器消息*/Receive.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {


// 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() {@Overridepublic void run() {


try {// 步骤 1:创建输入流对象 InputStreamis = socket.getInputStream();


// 步骤 2:创建输入流读取器对象 并传入输入流对象// 该对象作用:获取服务器返回的数据 isr = new InputStreamReader(is);br = new BufferedReader(isr);


// 步骤 3:通过输入流读取器对象 接收服务器发送过来的数据 response = br.readLine();


// 步骤 4:通知主线程,将接收的消息显示到界面 Message msg = Message.obtain();msg.what = 0;mMainHandler.sendMessage(msg);


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


}});


}});


/**


  • 发送消息 给 服务器*/btnSend.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {


// 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() {@Overridepublic void run() {


try {// 步骤 1:从 Socket 获得输出流对象 OutputStream// 该对象作用:发送数据 outputStream = socket.getOutputStream();


// 步骤 2:写入需要发送的数据到输出流对象中 outputStream.write((mEdit.getText().toString()+"\n").getBytes("utf-8"));// 特别注意:数据的结尾加上换行符才可让服务器端的 readline()停止阻塞


// 步骤 3:发送数据到服务端 outputStream.flush();


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


}});


}});


/**


  • 断开客户端 & 服务器的连接*/btnDisconnect.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {


try {// 断开 客户端发送到服务器 的连接,即关闭输出流对象 OutputStreamoutputStream.close();


// 断开 服务器发送到客户端 的连接,即关闭输入流读取器对象 BufferedReaderbr.close();


// 最终关闭整个 Socket 连接 socket.close();


// 判断客户端和服务器是否已经断开连接 System.out.println(socket.isConnected());


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


}});


}}

[](

)6.2 服务器 实现


  • 因本文主要讲解客户端,所以服务器仅仅是为了配合客户端展示;

  • 为了简化服务器使用,此处采用Mina框架


  1. 服务器代码请在eclipse平台运行

  2. 按照我的步骤一步步实现就可以无脑运行了


步骤 1:导入Mina


请直接移步到百度网盘:[下载链接(密码: q73e)](


)



步骤 2:创建服务器线程


TestHandler.java


package mina;// 导入包


public class TestHandler extends IoHandlerAdapter {


@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {System.out.println("exceptionCaught: " + cause);}


@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {System.out.println("recieve : " + (String) message);session.write("hello I am server");}


@Overridepublic void messageSent(IoSession session, Object message) throws Exception {


}


@Overridepublic void sessionClosed(IoSession session) throws Exception {System.out.println("sessionClosed");}


@Overridepublic void sessionOpened(IoSession session) throws Exception {System.out.println("sessionOpen");}


@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {}


}


步骤 3:创建服务器主代码


TestHandler.java


package mina;


import java.io.IOException;import java.net.InetSocketAddress;


import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.textline.TextLineCodecFactory;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;


public class TestServer {public static void main(String[] args) {NioSocketAcceptor acceptor = null;try {acceptor = new NioSocketAcceptor();acceptor.setHandler(new TestHandler());acceptor.getFilterChain().addLast("mFilter", new ProtocolCodecFilter(new TextLineCodecFactory()));acceptor.setReuseAddress(true);acceptor.bind(new InetSocketAddress(8989));} catch (Exception e) {e.printStackTrace();}}}


至此,客户端 & 服务器的代码均实现完毕。



[](

)6.3 测试结果


  • 点击 Connect按钮: 连接成功



  • 输入发送的消息,点击 Send 按钮发送



  • 服务器接收到客户端发送的消息



  • 点击 Receive From Message按钮,客户端 读取 服务器返回的消息



  • 点击 DisConnect按钮,断开 客户端 & 服务器的连接

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android Socket使用详解,android开发入门与实战作者