Android中socket通信的简单实现
时间:2022-07-27
本文章向大家介绍Android中socket通信的简单实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Android中socket通信简单实现,供大家参考,具体内容如下
socket通信需要有一个服务器和客户端,可以把同一个APP作为服务器跟客户端,也可以分开成两个APP。 先上个图:
这里以一个APP作为服务器跟客户端为示例
1、添加网络访问权限
<uses-permission android:name="android.permission.INTERNET" /
2、写服务器,在APP上启动
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
ServerSocket serverSocket = null;
public final int port = 9998;
private int i = 0;
public Server(){
//输出服务器的IP地址
try {
InetAddress addr = InetAddress.getLocalHost();
System.out.println("local host:"+addr);
serverSocket = new ServerSocket(port);
System.out.println("0k");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void startService(){
try {
Socket socket = null;
System.out.println("waiting...");
//等待连接,每建立一个连接,就新建一个线程
while(true){
socket = serverSocket.accept();//等待一个客户端的连接,在连接之前,此方法是阻塞的
System.out.println("connect to"+socket.getInetAddress()+":"+socket.getLocalPort());
new ConnectThread(socket).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("IOException");
e.printStackTrace();
}
}
//向客户端发送信息
class ConnectThread extends Thread{
Socket socket = null;
public ConnectThread(Socket socket){
super();
this.socket = socket;
}
@Override
public void run(){
try {
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
while(true){
i++;
String msgRecv = dis.readUTF();
System.out.println("msg from client:"+msgRecv);
dos.writeUTF(msgRecv + i);
dos.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
需要在线程中调用,调用方法:
new Thread(() - new Server().startService()).start();
3、客户端代码
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import androidx.appcompat.app.AppCompatActivity;
/**
* @author fenghaitao
* @time 2020年4月2日14:34:33
* scoket客户端连接测试
*/
public class SocketActivity extends AppCompatActivity {
//IP地址和端口号
public static String IP_ADDRESS = "";
public static int PORT = 9998;
//三个控件
EditText et_message = null; //需要发送的内容
Button bt_getAdress = null; //获取本机IP地址
Button bt_connect = null; //连接并发送
Button bt_startServer = null; //启动服务端
TextView tv_adress = null; //ip地址
TextView tv_reply = null; //服务器回复的消息
//handler
Handler handler = null;
Socket soc = null;
DataOutputStream dos = null;
DataInputStream dis = null;
String messageRecv = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket);
et_message = findViewById(R.id.et_message);
bt_getAdress = findViewById(R.id.bt_getAdress);
bt_connect = findViewById(R.id.bt_connect);
bt_startServer = findViewById(R.id.bt_startServer);
tv_adress = findViewById(R.id.tv_adress);
tv_reply = findViewById(R.id.tv_reply);
bt_getAdress.setOnClickListener(v - {
new Thread(() - {
try {
InetAddress addr = InetAddress.getLocalHost();
System.out.println("local host:"+addr);
runOnUiThread(() - tv_adress.setText(addr.toString().split("/")[1]));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}).start();
});
bt_startServer.setOnClickListener(v - {
new Thread(() - new Server().startService()).start();
Toast.makeText(SocketActivity.this,"服务已启动",Toast.LENGTH_SHORT).show();
});
bt_connect.setOnClickListener(v - {
IP_ADDRESS = tv_adress.getText().toString();
new ConnectionThread(et_message.getText().toString()).start();
});
handler = new Handler(msg - {
Bundle b = msg.getData(); //获取消息中的Bundle对象
String str = b.getString("data"); //获取键为data的字符串的值
tv_reply.append(str);
return false;
});
}
//新建一个子线程,实现socket通信
class ConnectionThread extends Thread {
String message = null;
public ConnectionThread(String msg) {
message = msg;
}
@Override
public void run() {
if (soc == null) {
try {
//Log.d("socket","new socket");
if ("".equals(IP_ADDRESS)) {
return;
}
soc = new Socket(IP_ADDRESS, PORT);
//获取socket的输入输出流
dis = new DataInputStream(soc.getInputStream());
dos = new DataOutputStream(soc.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
dos.writeUTF(message);
dos.flush();
messageRecv = dis.readUTF();//如果没有收到数据,会阻塞
Message msg = new Message();
Bundle b = new Bundle();
b.putString("data", messageRecv);
msg.setData(b);
handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
下面是xml页面代码
<?xml version="1.0" encoding="utf-8"?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SocketActivity"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
<Button
android:id="@+id/bt_getAdress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取IP地址"/
<TextView
android:id="@+id/tv_adress"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:textSize="20dp"
android:gravity="center"/
</LinearLayout
<Button
android:id="@+id/bt_startServer"
android:text="启动服务"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/
<EditText
android:id="@+id/et_message"
android:layout_marginTop="10dp"
android:hint="请输入发送信息"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/
<Button
android:id="@+id/bt_connect"
android:text="连接发送"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/
<TextView
android:id="@+id/tv_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="服务端返回消息:"
android:textSize="30sp"/
</LinearLayout
</LinearLayout
客户端跟服务器进行通信之前记得先启动服务器,如果端口被占用需要换个端口。
以上就是本文的全部内容,希望对大家的学习有所帮助。
- Consul微服务的配置中心体验篇
- 如何使用Sentry实现Hive/Impala的数据脱敏
- 如何使用Oozie API接口向Kerberos环境的CDH集群提交Shell作业
- Docker下redis的主从、持久化配置
- vuejs、eggjs、mqtt全栈式开发设备管理系统
- Xss和Csrf介绍
- GraphQL介绍&使用nestjs构建GraphQL查询服务
- 使用auth_request模块实现nginx端鉴权控制
- Docker学习之Docker镜像基本使用
- Docker学习之Centos7下安装
- Impala的Short-Circuit Reads
- js各种继承方式汇总
- Cloudera Navigator异常分析
- lodash源码分析之数组的差集
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析
- 这次,我把Android事件分发机制翻了个遍
- 网络请求框架OkHttp3全解系列 - (三)拦截器详解1:重试重定向、桥、缓存(重点)
- Python全栈(七)Flask框架之4.Flask模板继承与案例练习
- 你想要的系列:网络请求框架OkHttp3全解系列 - (四)拦截器详解2:连接、请求服务(重点)
- 不会玩阴阳师的我带你一键下载《阴阳师:百闻牌》所有卡牌并调用百度OCR识别文字信息
- 微信小程序生命周期学习笔记-页面篇
- Python 字典 使用技巧
- 微信小程序生命周期学习笔记-组件
- C语言入门系列之2.数据类型、运算符和表达式
- 树莓派的cpu与gpu通信设计浅析
- Python全栈(七)Flask框架之5.视图高级--类视图和蓝图
- Python全栈(六)项目前导之5.使用GitHub进行多人协同开发
- 附002.Nginx代理相关模块解析
- ApiBoot v2.3.x分支第一个版本发布,重构源码架构设计