【Android】使用Socket实现跨设备通讯
1 Socket 简介
Socket(套接字)是应用层与 TCP/IP 协议通信的中间软件抽象层,它是一组接口,用户只需面向 Socket 编程,即可实现跨设备(网络)通讯。
Socket 是 java 里的东西,不是 Android 特有的,使用 Socket 需要导入的类如下。
java.net.ServerSocket
java.net.Socket
(1)服务端主要接口调用
// 获取 socket
mServerSocket = new ServerSocket(port)
// port 为端口号,取值:0~65535间的整数,前1024个端口号为固定端口,一般不提供给程序员使用,之后为注册端口,为避免端口冲突,建议 port 值取大点
mSocket = mServerSocket.accept() //调用此方法会阻塞线程,建议在子线程中执行
// 读取对端数据
in = mSocket.getInputStream()
byte[] bt = new byte[50]
in.read(bt)
// 向对端发送数据
out = new PrintWriter(mSocket.getOutputStream())
out.print(content)
out.flush()
(2)客户端主要接口调用
// 获取 socket
mSocket = new Socket(ip, port) //调用此方法会阻塞线程,建议在子线程中执行
// ip 为服务端设备 ip 地址
// port 为端口号,取值:0~65535间的整数,前1024个端口号为固定端口,一般不提供给程序员使用,之后为注册端口,为避免端口冲突,建议 port 值取大点
// 读取对端数据
in = mSocket.getInputStream()
byte[] bt = new byte[50]
in.read(bt)
// 向对端发送数据
out = new PrintWriter(mSocket.getOutputStream())
out.print(content)
out.flush()
本文全部代码见→使用Socket实现跨设备通讯
2 项目结构
注意:2个设备必须在局域网中(连同一个wifi )
3 服务端(socket_S)
Server.java
package com.zhyan8.socket_s;
import android.os.Handler;
import android.os.Message;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server{
private ServerSocket mServerSocket;
private Socket mSocket;
private Handler mHandler;
private InputStream in;
private PrintWriter out;
private Object lock = new Object();
public Server(Handler handler, int port){
mHandler = handler;
try {
mServerSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void connect() {
new Thread() {
@Override
public void run() {
try {
synchronized (lock) {
if (mSocket!=null) {
return;
}
mSocket = mServerSocket.accept();
in = mSocket.getInputStream();
out = new PrintWriter(mSocket.getOutputStream());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void begin_listen() {
while (mSocket==null) {
connect();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
new Thread() {
@Override
public void run() {
try {
while (!mSocket.isClosed()) {
byte[] bt = new byte[50];
in.read(bt);
String content = new String (bt, "UTF-8" );
if (content!=null && !content.equals("")) {
Message msg = new Message();
msg.obj = content;
mHandler.sendMessage(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void send_msg(final String content) {
new Thread() {
@Override
public void run() {
out.print(content);
out.flush ();
}
}.start();
}
}
MainActivity.java
package com.zhyan8.socket_s;
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;
public class MainActivity extends AppCompatActivity {
private Server mServer;
private EditText et_msg;
private Button btn_send;
private TextView tv_msg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
et_msg = (EditText) findViewById(R.id.et_msg);
btn_send = (Button) findViewById(R.id.btn_send);
tv_msg = (TextView) findViewById(R.id.tv_msg);
btn_send.setOnClickListener(cl);
mServer = new Server(mHandler, 1111);
mServer.begin_listen();
}
private View.OnClickListener cl = new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = et_msg.getText().toString().trim();
if (content!=null && !content.equals("")) {
mServer.send_msg(content);
}
}
};
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
String content = (String) msg.obj;
tv_msg.setText(content);
}
};
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.zhyan8.socket_s.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="接收的消息:"
android:textSize="20sp"
android:gravity="center_vertical"/>
<TextView
android:id="@+id/tv_msg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center_vertical"/>
</LinearLayout>
<EditText
android:id="@+id/et_msg"
android:layout_width="match_parent"
android:layout_height="100dp"
android:textSize="30sp"
android:background="#ffcc66"/>
<Button
android:id="@+id/btn_send"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="发送"
android:textSize="30sp"
android:layout_marginTop="30dp"/>
</LinearLayout>
界面如下:
在 AndroidManifest.xml 文件的 manifest 标签下(与 application 同级)添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
4 客户端(socket_C)
Client.java
package com.zhyan8.socket_c;
import android.os.Handler;
import android.os.Message;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class Client{
private Socket mSocket;
private Handler mHandler;
private InputStream in;
private PrintWriter out;
private String ip;
private int port;
private Object lock = new Object();
Client(Handler handler, String ip, int port) {
mHandler = handler;
this.ip = ip;
this.port = port;
}
private void connect() {
new Thread() {
@Override
public void run() {
try {
synchronized (lock) {
if (mSocket!=null) {
return;
}
mSocket = new Socket(ip, port);
in = mSocket.getInputStream();
out = new PrintWriter(mSocket.getOutputStream());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void begin_listen() {
while (mSocket==null) {
connect();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
new Thread() {
@Override
public void run() {
try {
while (!mSocket.isClosed()){
byte[] bt = new byte[50];
in.read(bt);
String content = new String (bt, "UTF-8" );
if (content!=null && !content.equals("")) {
Message msg = new Message();
msg.obj = content;
mHandler.sendMessage(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void send_msg(final String content) {
new Thread() {
@Override
public void run() {
out.print(content);
out.flush();
}
}.start();
}
}
MainActivity.java
package com.zhyan8.socket_c;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Client mClient;
private EditText et_msg;
private Button btn_send;
private TextView tv_msg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
et_msg = (EditText) findViewById(R.id.et_msg);
btn_send = (Button) findViewById(R.id.btn_send);
tv_msg = (TextView) findViewById(R.id.tv_msg);
btn_send.setOnClickListener(cl);
mClient = new Client(mHandler, "192.168.0.104", 1111);
mClient.begin_listen();
}
private View.OnClickListener cl = new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = et_msg.getText().toString().trim();
if (content!=null && !content.equals("")) {
mClient.send_msg(content);
}
}
};
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
String content = (String) msg.obj;
tv_msg.setText(content);
}
};
}
activity_main.xml 同第3节。
在 AndroidManifest.xml 文件的 manifest 标签下(与 application 同级)添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
5 效果展示
客户端:
服务端:
声明:本文转自【Android】使用Socket实现跨设备通讯
【Android】使用Socket实现跨设备通讯的更多相关文章
- AllJoyn+Android开发案例-android跨设备调用方法
AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...
- Android 通过Socket 和服务器通讯
Extends:(http://www.cnblogs.com/likwo/p/3641135.html) Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大 ...
- android 跨进程通讯 AIDL
跨进程如何通讯?两个进程无法直接通讯,通过Android系统底层间接通讯.基于service的aidl实现跨进程通讯. 什么叫AIDL? Android interface definition la ...
- android 史上最简单易懂的跨进程通讯(Messenger)!
不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...
- Android为TV端助力 史上最简单易懂的跨进程通讯(Messenger)!
不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...
- Android 基于Socket的聊天应用(二)
很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的 ...
- AppCompat v21 — Android 5.0之前版本设备的Material Design实现
博客原文地址:http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html,要想打 ...
- [置顶]
Xamarin android中使用signalr实现即时通讯
前面几天也写了一些signalr的例子,不过都是在Web端,今天我就来实践一下如何在xamarin android中使用signalr,刚好工作中也用到了这个,也算是总结一下学到的东西吧,希望能帮助你 ...
- 以面向对象的思维,搭建Android与多ble蓝牙设备并发通讯小框架
Android连接多蓝牙设备.蓝牙与多设备连接.蓝牙ble多设备并发操作.Android连接不了.Android ble开发框架.Android 连接蓝牙总结 前言 小白请绕道百度,本文适合有一定An ...
- IOT设备通讯,MQTT物联网协议,MQTTnet
一.IOT设备的特性 硬件能力差(存储能力基本只有几MB,CPU频率低连使用HTTP请求都很奢侈) 系统千差万别(Brillo,mbedOS,RIOT等) 如使用电池供电,电量消耗敏感 如果是小设备, ...
随机推荐
- 【MicroPython】生成Q(string)符号表文件 - py\makeqstrdefs.py
脚本使用格式 python py/makeqstrdefs.py [command] [mode] [input-file] [output-directory] [output-file] comm ...
- PageHelper 分页不起作用
将 reasonable 设置为 false .
- Go-插入排序
// InsertSort 插入排序 // 思路: // 1. 第一个元素默认是已经排好序的 // 2. 从第二个元素开始,依次比较前面一个元素中,如果小于则交换位置 // 插入排序思路: 将一个元素 ...
- [转帖]MySQL如何进行索引重建操作?
MySQL如何进行索引重建操作? - 潇湘隐者 - 博客园 (cnblogs.com) 在MySQL数据库中,没有类似于SQL Server数据库或Oracle数据库中索引重建的语法(ALTER IN ...
- [转帖]tgz 安装clickhouse
一.什么是clickhouse ClickHouse是开源的列式存储数据库(DBMS),主要用于在线处理查询(OLAP),能够使用SQL查询实时生成数据分析报告. 下面介绍下安装clickhouse. ...
- [转帖]kafka搭建kraft集群模式
kafka2.8之后不适用zookeeper进行leader选举,使用自己的controller进行选举 1.准备工作 准备三台服务器 192.168.3.110 192.168.3.111 192. ...
- [转帖]一次SSL握手异常,我发现JDK还有发行版区别
https://www.cnblogs.com/codelogs/p/16633704.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 最近,我们一个 ...
- [转帖]NGINX 局限太多,Cloudflare 最终放弃它并用 Rust 自研了全新替代品
https://www.infoq.cn/news/s2fa603MsEENsCmibTYI 长期以来,NGINX 可以说是网站安全和托管服务提供商 Cloudflare 的核心,是其所使用的基础软件 ...
- 使用Grafana 监控 SQLSERVER数据库
使用Grafana 监控 SQLSERVER数据库 1.获取镜像信息以及启动镜像 docker pull awaragi/prometheus-mssql-exporter docker run -e ...
- NutUI 4.0 正式发布!
作者: 京东零售 NutUI NutUI 4.0 Github 地址:github.com/jdf2e/nutui NutUI 4.0 官网:nutui.jd.com 前言 技术日异月新.发展创新.持 ...