【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等) 如使用电池供电,电量消耗敏感 如果是小设备, ...
随机推荐
- Laravel - blade 模板继承的使用
1. 模板文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- Laravel - Eloquent 更新数据
public function ormUpdate() { # 1.通过模型更新数据 /* $student = Student::find(14); ...
- Laravel : Eloquent 新增
public function ormCreate() { # 1. 使用模型新增 ->save() /* ...
- c#下使用WM_COPYDATA
[DllImport("User32.dll")] public static extern int SendMessage(IntPtr hwnd, int msg, int w ...
- [转帖]从小白到精通:揭秘perf工具的全部功能与操作技巧
https://zhuanlan.zhihu.com/p/664396453 目录 收起 一.引言 二.理解perf工具的基本概念 三.安装与配置perf工具 3.1.不同操作系统的perf工具安 ...
- [转帖]【KingbaseES】sys_dump逻辑备份工具详解
KingbaseES逻辑备份还原工具提供了数据库对象一级的联机备份还原功能,备份对象包括: 数据库 模式 表 视图 约束 权限 触发器 函数 序列 逻辑备份的输出格式包括: 二进制 SQL脚本 此外, ...
- [转帖]harbor-db restarting问题
现象: 在安装harbor后,启动时发现harbor-db 一直是restarting,/harbor-jobservice,/harbor-core 这两是starting 状态,如下图 解决: 1 ...
- [转帖]Kafka之ack机制
前言 之前的博客里说了,Kafka的消息同步是一种ISR机制,本质上是"完全同步"的一种优化. 都在说,消息被ISR中所有副本都写入才算写入成功.但是这样未免定的太死板了,所以,K ...
- [转帖]Linux系统语言设置和locale命令详解
简介 Linux系统可以用locale命令查看语言设置,查看中英文环境,具体操作如下. 操作 1.查看当前安装有那些语言: [root@localhost /]# locale -a 2.当前语言相关 ...
- 【转帖】Linux性能优化(十四)——CPU Cache
一.CPU Cache 1.CPU Cache简介 CPU Cache是位于CPU与内存之间的临时存储器,容量比内存小但交换速度却比内存要快得多.Cache的出现主要是为了解决CPU运算速度与内存读写 ...