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实现跨设备通讯的更多相关文章

  1. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

  2. Android 通过Socket 和服务器通讯

    Extends:(http://www.cnblogs.com/likwo/p/3641135.html) Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大 ...

  3. android 跨进程通讯 AIDL

    跨进程如何通讯?两个进程无法直接通讯,通过Android系统底层间接通讯.基于service的aidl实现跨进程通讯. 什么叫AIDL? Android interface definition la ...

  4. android 史上最简单易懂的跨进程通讯(Messenger)!

    不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...

  5. Android为TV端助力 史上最简单易懂的跨进程通讯(Messenger)!

    不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...

  6. Android 基于Socket的聊天应用(二)

    很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的 ...

  7. AppCompat v21 — Android 5.0之前版本设备的Material Design实现

    博客原文地址:http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html,要想打 ...

  8. [置顶] Xamarin android中使用signalr实现即时通讯

    前面几天也写了一些signalr的例子,不过都是在Web端,今天我就来实践一下如何在xamarin android中使用signalr,刚好工作中也用到了这个,也算是总结一下学到的东西吧,希望能帮助你 ...

  9. 以面向对象的思维,搭建Android与多ble蓝牙设备并发通讯小框架

    Android连接多蓝牙设备.蓝牙与多设备连接.蓝牙ble多设备并发操作.Android连接不了.Android ble开发框架.Android 连接蓝牙总结 前言 小白请绕道百度,本文适合有一定An ...

  10. IOT设备通讯,MQTT物联网协议,MQTTnet

    一.IOT设备的特性 硬件能力差(存储能力基本只有几MB,CPU频率低连使用HTTP请求都很奢侈) 系统千差万别(Brillo,mbedOS,RIOT等) 如使用电池供电,电量消耗敏感 如果是小设备, ...

随机推荐

  1. 你老了,别搞IT了……

    你老了,别搞IT了-- [来源]

  2. 在Winform系统开发中,使用MediatR来实现类似事件总线的消息处理

    MediatR是一款进程内的消息订阅.发布框架,可实现请求/响应.命令.查询.通知和事件的消息传递,解耦了消息处理器和消息之间耦合.提供了Send方法用于发布到单个处理程序.Publish方法发布到多 ...

  3. [转帖]深入JVM - Code Cache内存池

    深入JVM - Code Cache内存池 1. 本文内容 本文简要介绍JVM的 Code Cache(本地代码缓存池). 2. Code Cache 简要介绍 简单来说,JVM会将字节码编译为本地机 ...

  4. [转帖]一文快速入门 ClickHouse

    https://zhuanlan.zhihu.com/p/621480049 什么是clickhouse ClickHouse是一种OLAP类型的列式数据库管理系统,这里有两个概念:OLAP.列式数据 ...

  5. minio性能测试

    minio性能测试 minio的使用 前期使用了s3fs 但是想验证一下性能相关, 所以使用今天简单验证了一下, 其实也可以使用一下fio 但是s3fs 是对象存储 没有修改 只有上传, 所以感觉还是 ...

  6. 【一个构想】pull方式获取expoter上的数据,如何更加精简?

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu 公众号:一本正经的瞎扯 背景 已知:在prometheus中,每个业务节点通过prometheu ...

  7. python.exe和pythonw.exe的区别(区分.py、.pyw、.pyc、.pyo文件)

    python和pythonw 在Windows系统搭建好Python的环境后,进入Python的安装目录,大家会发现目录中有python.exe和pythonw.exe两个程序.如下图所示: 它们到底 ...

  8. 【主流技术】实战之 Spring Boot 中集成微信支付(小程序)

    前言 微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的. 以下是经过真实商业项目实践的集成步骤,包括注册流程.调用过程.代码demo(经过脱敏)等,希望我的分享 ...

  9. 数据挖掘[一]---汽车车交易价格预测(测评指标;EDA)

    题目出自阿里天池赛题链接:零基础入门数据挖掘 - 二手车交易价格预测-天池大赛-阿里云天池 相关文章: 特征工程详解及实战项目[参考] 数据挖掘---汽车车交易价格预测[一](测评指标:EDA) 数据 ...

  10. 【一】LaTeX的安装和使用、安装TeXstudio、中文界面输出设置

    安装方法一:(推荐) 下载链接·:http://tug.org/texlive/acquire-netinstall.html 下载zip,然后运行Windows批处理脚本(install-tl-wi ...