Android Socket 使用详解,android 开发入门与实战作者
// 断开 客户端发送到服务器 的连接,即关闭输出流对象 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
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
框架
服务器代码请在
eclipse
平台运行按照我的步骤一步步实现就可以无脑运行了
步骤 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
按钮,断开 客户端 & 服务器的连接
评论